uWebsocket在.message回调上下文外发送WebSocket消息的类型匹配问题
uWebsocket外部函数WebSocket指针类型定义解决方案
问题根因
uWS::WebSocket是三参数模板类,你之前仅传入1个模板参数的写法和实际实例化的类型不匹配,因此编译失败。
uWS::WebSocket的三个模板参数含义如下:
- 第一个参数:布尔值,代表是否为SSL加密的WebSocket连接,使用
uWS::App()(非SSL)对应false,使用uWS::SSLApp()对应true - 第二个参数:布尔值,代表是否启用perMessageDeflate压缩,uWS默认开启该能力,因此填
true - 第三个参数:你自定义的WebSocket上下文数据类型,即注册ws路由时传入的
SocketData结构体类型
另外需要注意一个隐藏坑:你原本把SocketData定义在RelaySocket函数内部,属于函数局部类型,外部函数无法访问该类型,必须把SocketData的定义移到函数外部的公共作用域。
可运行的完整代码示例
// SocketData必须定义在公共作用域,不能放在RelaySocket函数内部 struct SocketData{ // 按需添加自定义上下文数据,暂时不需要可以留空 }; // 传入完整的三个模板参数即可正常编译 void SocketResponse(uWS::WebSocket<false,true,SocketData> *ws ){ ws->send("test"); std::cout<< "test"<<std::endl; }; void RelaySocket(){ uWS::App() .listen(8766, [](auto *listen_socket){ if(listen_socket){ std::cout<< "Listening on port" << 8766<< std::endl; }; }) .ws<SocketData>("/*",uWS::TemplatedApp<false>::WebSocketBehavior<SocketData> { .open = [](auto *ws){ std::cout<< "test"<< std::endl; }, .message = [](auto *ws, std::string_view message, uWS::OpCode opCode){ ws->send("My message"); // 现在可以正常调用外部函数 SocketResponse(ws); } }).run(); }
跨线程推送补充说明
如果你要在独立线程中主动向客户端推送消息,注意uWS的ws->send方法不是线程安全的,不能直接在非uWS事件循环的线程中调用。可以按以下逻辑处理:
- 维护一个线程安全的消息队列,独立线程仅往队列中写入待发送的消息和对应的连接标识
- 调用uWS事件循环的
defer方法,在uWS主线程中从队列取消息执行发送操作
内容的提问来源于stack exchange,提问作者Tacne
相关产品推荐
相关产品推荐

