WebSocket 客户端 DLL 模块设计说明(基于 WebSocket++ + Boost.Asio)

WebSocket 客户端 DLL 模块设计说明(基于 WebSocket++ + Boost.Asio)

📌 目录


一、模块总览

本模块为一个跨平台可复用的 WebSocket 客户端库,支持 C 风格导出接口,供第三方程序以 DLL 动态链接方式调用。

💡 模块组成

复制代码
┌──────────────────────────────┐
│ WebSocketClientExport.h/cpp │ ← DLL 导出函数(外部调用)
├──────────────────────────────┤
│ WebSocketClientLibrary.h/cpp│ ← C++ 单例封装(中转层)
├──────────────────────────────┤
│ WebSocketImpl.h/cpp         │ ← 实现类(使用 WebSocket++ + Boost.Asio)
└──────────────────────────────┘

二、导出接口说明(EXPORTS)

复制代码
ini复制代码LIBRARY "WebScoket"

EXPORTS
    CreateWebSocketClient          @1  NONAME
    StartWebSocketClient           @2  NONAME
    StopWebSocketClient            @3  NONAME
    RegisterMessageCallback        @4  NONAME
    RegisterReconnectCallback      @5  NONAME
    SendHeartbeat                  @6  NONAME
    SendDisconnectNotice           @7  NONAME
    IsWebSocketClientConnecting    @8  NONAME
    IsWebSocketClientConnected     @9  NONAME
    RegisterConnectedCallback      @10 NONAME

三、状态变量功能解读

变量名 类型 作用说明
is_connected_ std::atomic<bool> 是否连接成功(open 状态)
is_connecting_ std::atomic<bool> 是否正在连接中
connect_failed_ std::atomic<bool> 本次连接是否失败
user_requested_stop_ std::atomic<bool> 标记是否是手动断开
is_reconnecting_ std::atomic<bool> 当前是否处于自动重连中
auto_reconnect_enabled_ bool 是否启用自动重连逻辑
has_reported_reconnect_result_ std::atomic<bool> 避免 reconnect_callback 多次调用
last_disconnect_reason_ enum 枚举 上一次断开的原因
last_uri_ std::string 上次连接地址,便于重连复用

四、连接启动流程详解

c++ 复制代码
A[调用 StartWebSocketClient()] --> B[设置连接标志 is_connecting_]
B --> C[获取 ws 连接对象]
C --> D{是否成功?}
D -- 否 --> E[返回 false]
D -- 是 --> F[发起连接 ws_client.connect(con)]
F --> G[创建线程 run io_context]
G --> H[等待连接成功(最多 3 秒)]
H --> I{is_connected_ 是否为 true}
I -- 否 --> E
I -- 是 --> J[返回 true,连接建立成功]

五、事件回调说明

✅ on_open

  • 设置状态 is_connected_ = true
  • 若当前是重连阶段,则回调 reconnect_callback_(true)
  • 否则(首次连接)调用 connected_callback_()

✅ on_fail

  • 设置 connect_failed_ = true
  • 若当前是重连阶段,则回调 reconnect_callback_(false)

✅ on_close

  • 若 user_requested_stop_ == true,表示手动断开 → 不自动重连
  • 若不是手动断开,等待 30 秒后触发自动重连 StartWebSocketClient(last_uri_, true)

六、消息发送流程

c++ 复制代码
void WebSocketImpl::Send(const std::string& message)

步骤:

  1. 判断是否已连接 is_connected_
  2. 获取连接对象 get_con_from_hdl
  3. 检查状态是否为 open
  4. 使用 ws_client.send() 发送消息

七、心跳与断连 JSON 数据格式

🔁 心跳请求(msgType: 1)

json 复制代码
{
  "msgType": 1,
  "deviceKey": "xxx",
  "tgt": "xxx",
  "sndaId": "xxx"
}

❌ 主动断连通知(msgType: 2)

json 复制代码
{
  "msgType": 2,
  "deviceKey": "xxx",
  "tgt": "xxx",
  "sndaId": "xxx"
}

八、自动重连机制

✅ 触发条件:

  • 非 Stop() 主动断开
  • 设置了 auto_reconnect_enabled_ = true
  • 当前不是重连中(避免重复)

✅ 重连逻辑:

c++ 复制代码
std::thread([this] {
    ::Sleep(30000); // 延迟 30 秒
    bool success = this->StartWebSocketClient(this->last_uri_, true);
    if (!success && reconnect_callback_) {
        reconnect_callback_(false);
    }
}).detach();

九、首次连接与重连回调机制对比

情况 回调函数 是否只触发一次
首次连接成功 connected_callback_() 是
重连成功 reconnect_callback_(true) 是(防止重复通过标志)
重连失败 reconnect_callback_(false) 是(只触发一次)

通过 has_reported_reconnect_result_ 原子变量保证任意一次连接尝试最多调用一次回调。


十、完整调用示例

c++ 复制代码
WebSocketHandle* handle = nullptr;

// 创建客户端
CreateWebSocketClient(&handle);

// 注册回调
RegisterMessageCallback(handle, [](const char* msg) {
    printf("收到消息:%s\n", msg);
});

RegisterConnectedCallback(handle, []() {
    printf("首次连接成功\n");
});

RegisterReconnectCallback(handle, [](bool success) {
    printf("重连%s\n", success ? "成功" : "失败");
});

// 启动连接(支持重连)
StartWebSocketClient(handle, "ws://127.0.0.1:9000/ws", true);

// 心跳
SendHeartbeat(handle, "TGT-XYZ", "device-key", "user-id");

// 主动断连
SendDisconnectNotice(handle, "TGT-XYZ", "device-key", "user-id");

// 查询连接状态
bool isConnected = IsWebSocketClientConnected(handle);
bool isConnecting = IsWebSocketClientConnecting(handle);

// 停止连接
StopWebSocketClient(handle);
相关推荐
Black蜡笔小新26 分钟前
上云网关/端口穿透/设备上云EasyNTS:无需公网IP、也不改防火墙,设备怎么从内网跑到外网去
网络·网络协议·tcp/ip
Escalating_xu2 小时前
【Linux 网络编程】五种 I/O 模型与非阻塞 I/O:从“等数据”到正确处理 EAGAIN
java·linux·网络
默|笙3 小时前
【Linux网络】传输层协议TCP(3)滑动窗口、流量控制
linux·网络·tcp/ip
xiaoye-duck4 小时前
《C++ 项目:手写大模型接入 SDK》ChatGPT接口设计(中):全量响应实现和测试
网络·c++·语言模型·chatgpt
无言听风雨丶5 小时前
systemd 与信号 / 僵尸进程:Linux 进程管理的底层逻辑与排错
linux·服务器·网络
g5zhu58966 小时前
没有公网ip的情况下,本地能ping服务器服务器不能ping本地,让服务器能访问本地某端口的简单方法
服务器·网络协议·tcp/ip
SDWAN_Cheap6 小时前
BGP是什么,广播IP是什么?两个容易混淆的概念拆解
网络·tcp/ip·bgp·广播ip
程序员JerrySUN6 小时前
PCIe Gen5 SSD 为什么读得快、写得慢?从存储原理到 Linux 性能实测
linux·服务器·网络
guizhoumen6 小时前
net core下WebSocket请求总是断开的解决方案
网络·websocket·网络协议
HKT_China6 小时前
香港电讯河套区创新科技中心暨AI机楼揭幕,以网络基建助力北部都会区发展
网络·ai