关闭阻塞客户端连接webscokettpp客户端从c# UI应用程序



我正在使用webscokettpp c++客户端读取从web服务器发布的数据。我有一个带有测试按钮的c# UI应用程序,它调用c++客户端dll来获取和显示发布在套接字上的数据。当测试按钮被点击数据被正确张贴在UI第二次我想关闭现有的连接,打开新的连接再次获得结果。但是在第一次运行之后,程序再也不会从c.run()返回;在下面的代码中。我使用的例子来自https://github.com/zaphoyd/websocketpp/blob/master/examples/echo_client/echo_client.cpp

 #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;
         if(pt.get<std::string>("test") = "close" ){
          //Code reaches here after end of first run but never comes out of c.run()
            c->close(hdl, websocketpp::close::status::normal, "Success");
            hdl.reset();
         }
        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;
        }
    }

我正试图找出一种方法来主要方法来c.run()当条件如果(pt.get("test") = "close")发生

当你使用客户端时,你需要在一个单独的线程上调用run();这将允许您在单独的线程上完成时优雅地停止客户端。IIRC然后run()将退出,这意味着您可以关闭线程并在需要时重新开始。

请参阅此常见问题解答,特别是"如何干净地退出基于Asio传输的程序";部分。停止exe强制关闭连接是一个坏主意,可能会导致微妙的错误。

基于Asio传输的客户端和服务器使用Asio库的底层io_service来处理异步网络操作。io_service的标准行为是运行直到没有异步操作剩余,然后返回。当使用Asio传输时,WebSocket++的行为就像一个标准的Asio应用程序。如果你想让你的WebSocket++/Asio程序停止网络操作并干净地关闭所有套接字,你需要做以下操作:

对于服务器,调用websocketpp::transport::asio::endpoint::stop_listening启动服务器侦听套接字的关闭。对于客户端,如果您使用websocketpp::transport::asio::endpoint::start_perpetual使用永久模式,请使用websocketpp::transport::asio::endpoint::stop_perpetual禁用它。对于两者,运行websocketpp::endpoint::close或websocketpp::connection::close对所有当前未完成的连接。这将为这些连接启动WebSocket关闭握手等待。亚洲是异步的。当对上述方法(stop_listening, close等)的调用完成后,服务器仍然在监听,连接仍然是活动的,直到io_service绕过异步处理套接字和WebSocket协议关闭握手。当所有操作完成后,io_service::run方法将自动干净地退出。警告:Asio的io_service有一个叫做stop的方法。websocketpp::transport::asio::endpoint::stop包装这个方法。虽然这个操作的名字听起来很温和,但它是一个功能强大且具有破坏性的操作,只应该在特殊情况下使用。如果您没有很好的理由使用io_service::stop或endpoint::stop,那么您的程序很可能出现故障,并可能表现出不稳定的行为。具体来说,io_service::stop完全停止事件的处理。这不会给当前操作(如套接字关闭握手)完成的机会。它将使您的套接字处于悬空状态,可能会调用操作系统级超时或其他错误。

相关内容

  • 没有找到相关文章

最新更新