如何使用websocket websocketpp发送和接收消息?

时间:2020-05-07 10:59:30

标签: c++ websocket

如何使用websocket websocketpp发送和接收消息?

我在C ++中有一个小代码,我正在尝试使用websocketpp库

我以一个可用的客户端/服务器为例,但终端仅显示它已连接。

https://github.com/zaphoyd/websocketpp

我是C ++的初学者,因此我感谢能提供的帮助。因为我正在学习语言和技术网络套接字。

服务器

#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;
}

客户

#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;
    }
}

1 个答案:

答案 0 :(得分:0)

您需要使用客户端实例调用send()方法; here中记录了各种重载。编辑:我可以看到实际上您已经在调用它,但是在错误的位置。因为它在on消息处理程序中,所以它仅在收到消息时才发送。而且服务器代码本身不会发送任何消息,因此客户端中的发送将永远不会触发。 websocketpp示例将发送置于打开处理程序中,但是在演示之外,这是一个非常无用的用例。

通常,您希望直接从应用程序代码中调用send。棘手的是如何协商一个事实,即必须先调用run()才能对客户端执行任何操作,而run是阻塞调用(这意味着以后不能调用send)。答案是有一个专用于调用run()的线程,它允许您在主线程(或所需的任何线程)上调用send()。

既然您说您是C ++的新手,我建议您首先学习线程:学习如何启动和优雅地停止线程,并了解线程安全性。有几种在C ++中使用线程的方法,但在这种情况下,我建议您看一下std :: thread。

一旦您了解了如何在C ++中使用线程,然后尝试将其构建到您的应用程序中。最终,为您的客户端创建一个类来处理线程并发送消息等是一个好主意。

一旦您能正常工作,我建议您阅读websocketpp FAQ),尤其是“如何彻底退出基于Asio Transport的程序”部分。