0

我修改了websocket++ 回显服务器示例以使用多个线程:

#include <iostream>
#include <boost/thread/thread.hpp>
#include <websocketpp/config/asio_no_tls.hpp>
#include <websocketpp/server.hpp>

typedef websocketpp::server<websocketpp::config::asio> server;

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 server::message_ptr message_ptr;

// Define a callback to handle incoming messages
void on_message(server* s, websocketpp::connection_hdl hdl, message_ptr msg)
{
    try {
        s->send(hdl, msg->get_payload(), msg->get_opcode());
    } catch (const websocketpp::lib::error_code& e) {
        std::cout << "Echo failed because: " << e << "(" << e.message() << ")" << std::endl;
    }
}

int main()
{
    // Create a server endpoint
    server echo_server;
    boost::asio::io_service io_service;
    try {

        // Initialize Asio
        echo_server.init_asio(&io_service);

        // Register our message handler
        echo_server.set_message_handler(bind(&on_message, &echo_server, ::_1, ::_2));

        // Listen on port 9002
        echo_server.set_reuse_addr(true);
        echo_server.listen(9002);

        // Start the server accept loop
        echo_server.start_accept();

        boost::thread_group threadpool;
        threadpool.create_thread(boost::bind(&boost::asio::io_service::run, &io_service));
        threadpool.create_thread(boost::bind(&boost::asio::io_service::run, &io_service));
        threadpool.join_all();
    } catch (websocketpp::exception const& e) {
        std::cout << e.what() << std::endl;
    } catch (...) {
        std::cout << "other exception" << std::endl;
    }
}

我使用一个异步发送许多消息的客户端进行连接。然后服务器崩溃:

2016-08-31 13:05:44] [info] asio async_read_at_least error: system:125 (Operation canceled)
[2016-08-31 13:05:44] [error] handle_read_frame error: websocketpp.transport:2 (Underlying Transport Error)
terminate called after throwing an instance of 'std::bad_weak_ptr'
  what():  bad_weak_ptr

Thread Safety 上的 websocket++ 手册来看,我所做的应该是线程安全的:

Asio 传输为端点提供完整的线程安全性。使用 io_service 线程池,其中多个线程正在调用 io_service.run();

...

所有核心传输都保证给定连接的处理程序将被序列化。当传输和并发策略支持端点并发时,任何涉及 connection_hdl 的东西都应该是线程安全的。ie 可以安全地将connection_hdls 传递给其他线程,无限期地存储它们,并随时从任何线程调用将它们作为参数的端点方法。

我在这里想念什么?


我使用的客户端是基于 NodeJS 的:

客户端.js

var port =  9002;
var times = 10000;
var WebSocket = require("ws");
var ws = new WebSocket("ws://localhost:" + port);

ws.on('open', function open() {
    for(var i = 0; i < times; ++i) {
        ws.send(i);
    }
});

通过以下方式开始:

$ npm install --save ws
$ node client.js
4

0 回答 0