You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.01 03:15:02