Reputation: 3082
How to sending and receiving messages with websocket websocketpp?
I have a small code in C ++ and I'm trying to use the websocketpp lib
I am using the example of a client / server available but the terminal only shows that it has been connected.
https://github.com/zaphoyd/websocketpp
I'm a beginner in C ++ so I appreciate the attention I can help. Because I am studying the language and technology websocket.
Server
#include <iostream>
// WebService
#include <set>
#include <websocketpp/config/asio_no_tls.hpp>
#include <websocketpp/server.hpp>
#include <functional>
typedef websocketpp::server<websocketpp::config::asio> server;
class utility_server {
public:
utility_server() {
// Set logging settings
m_endpoint.set_error_channels(websocketpp::log::elevel::all);
m_endpoint.set_access_channels(websocketpp::log::alevel::all ^ websocketpp::log::alevel::frame_payload);
// Initialize Asio
m_endpoint.init_asio();
// Set the default message handler to the echo handler
m_endpoint.set_message_handler(std::bind(
&utility_server::echo_handler, this,
std::placeholders::_1, std::placeholders::_2
));
}
void echo_handler(websocketpp::connection_hdl hdl, server::message_ptr msg) {
// write a new message
m_endpoint.send(hdl, msg->get_payload(), msg->get_opcode());
}
void run() {
// Listen on port 9002
m_endpoint.listen(9002);
// Queues a connection accept operation
m_endpoint.start_accept();
// Start the Asio io_service run loop
m_endpoint.run();
}
private:
server m_endpoint;
};
int main()
{
utility_server s;
s.run();
return 0;
}
Client
#include <websocketpp/config/asio_no_tls_client.hpp>
#include <websocketpp/client.hpp>
#include <iostream>
typedef websocketpp::client<websocketpp::config::asio_client> client;
using websocketpp::lib::placeholders::_1;
using websocketpp::lib::placeholders::_2;
using websocketpp::lib::bind;
// pull out the type of messages sent by our config
typedef websocketpp::config::asio_client::message_type::ptr message_ptr;
// This message handler will be invoked once for each incoming message. It
// prints the message and then sends a copy of the message back to the server.
void on_message(client* c, websocketpp::connection_hdl hdl, message_ptr msg) {
std::cout << "on_message called with hdl: " << hdl.lock().get()
<< " and message: " << msg->get_payload()
<< std::endl;
websocketpp::lib::error_code ec;
c->send(hdl, msg->get_payload(), msg->get_opcode(), ec);
if (ec) {
std::cout << "Echo failed because: " << ec.message() << std::endl;
}
}
int main(int argc, char* argv[]) {
// Create a client endpoint
client c;
std::string uri = "ws://localhost:9002";
if (argc == 2) {
uri = argv[1];
}
try {
// Set logging to be pretty verbose (everything except message payloads)
c.set_access_channels(websocketpp::log::alevel::all);
c.clear_access_channels(websocketpp::log::alevel::frame_payload);
// Initialize ASIO
c.init_asio();
// Register our message handler
c.set_message_handler(bind(&on_message, &c, ::_1, ::_2));
websocketpp::lib::error_code ec;
client::connection_ptr con = c.get_connection(uri, ec);
if (ec) {
std::cout << "could not create connection because: " << ec.message() << std::endl;
return 0;
}
// Note that connect here only requests a connection. No network messages are
// exchanged until the event loop starts running in the next line.
c.connect(con);
// Start the ASIO io_service run loop
// this will cause a single connection to be made to the server. c.run()
// will exit when this connection is closed.
c.run();
}
catch (websocketpp::exception const& e) {
std::cout << e.what() << std::endl;
}
}
Upvotes: 1
Views: 2864
Reputation: 429
You need to call the send() method using the client instance; the various overloads are documented here. EDIT: I can see in fact you are already calling it, but in the wrong place. Because it is in the on message handler, it will only send when it receives a message. And the server code does not send any messages itself, so the send in the client will never trigger. The websocketpp example puts the send in the open handler, but beyond a demo this is a pretty useless use case.
More often than not, you want to be calling send directly from your application code. The tricky bit is how to negotiate the fact that you have to call run() before you can do anything with the client, and run is a blocking call (which means you can't call send afterwards). The answer to this is to have one thread dedicated to calling run(), which allows you to call send() on the main thread (or whichever thread you want).
Since you say you're new to C++ I'd suggest learning about threads first: learn how to start them and stop them gracefully, and learn about thread safety. There are a few ways to use threads in C++, but I'd recommend looking at std::thread in this case.
Once you understand how to use threads in C++, then try to build that into your application. Eventually it would be a good idea to create a class for your client which deals with the thread and sending messages etc.
Once you get something working I'd recommend reading the websocketpp FAQ), particularly the "How do I cleanly exit an Asio transport based program" section.
Upvotes: 1