websocat与websocketpp服务器配合能否正常处理关闭握手?
问题1:websocat能否正常处理WebSocket关闭握手?
websocat是符合RFC6455标准的成熟WebSocket工具,默认完全支持标准关闭握手流程,你当前遇到的超时问题基本可以排除是websocat的能力缺陷导致,后续你可以用浏览器WebSocket、wscat等其他客户端做交叉测试验证。
问题2:关闭连接的操作是否存在错误?
你的代码存在非常明显的错误:
- websocketpp基于Asio异步事件驱动模型实现,所有事件回调(包括你用到的
set_open_handler绑定的回调)都运行在run()方法启动的IO事件循环线程中,你直接在回调内调用std::this_thread::sleep_for(3s)会完全阻塞整个事件循环,这3秒内所有网络IO收发、定时器调度都会暂停。 - 即使你在sleep结束后调用了
close()方法,关闭帧的发送、后续客户端关闭响应的接收也都依赖事件循环调度,之前的阻塞已经打乱了IO时序,非常容易触发关闭超时。
正确的实现方式应该用异步定时器实现延迟关闭,绝对不能在事件回调内做阻塞操作,示例逻辑如下:
#include <websocketpp/common/asio.hpp> // 正确的延迟关闭实现,用异步定时器不阻塞事件循环 void on_open_connection(server * srv, websocketpp::connection_hdl hdl) { auto timer = std::make_shared<websocketpp::lib::asio::steady_timer>(srv->get_io_service()); timer->expires_after(std::chrono::seconds(3)); timer->async_wait([srv, hdl, timer](const websocketpp::lib::error_code& ec) { if (ec) return; using namespace websocketpp::close::status; auto conn = srv->get_con_from_hdl(hdl); conn->close(normal, get_string(normal)); }); }
问题3:为什么关闭握手超时的时候会触发on_close处理函数?
这是websocketpp的标准设计:on_close是连接生命周期的最终回调,无论连接是正常完成关闭握手、还是关闭握手超时、网络异常断开、主动强制终止等任何原因导致连接最终关闭,都会触发这个回调,用来给上层业务做统一的资源清理逻辑。
你可以在on_close内通过get_con_from_hdl拿到连接对象,调用get_close_code()、get_close_reason()等方法获取具体的关闭原因,区分是正常关闭还是异常超时关闭。
内容的提问来源于stack exchange,提问作者Dorian
相关产品推荐
相关产品推荐

