WebSocket模块使用文档¶
WebSocket模块是SOUI4提供的一个基于WebSocket协议的通信模块,支持客户端和服务器端的WebSocket通信。该模块在components/ws目录下实现。
模块概述¶
WebSocket模块提供了以下功能:
- WebSocket客户端实现
- WebSocket服务器实现
- 支持TCP和TLS安全连接
- 支持文本和二进制数据传输
- 支持心跳检测机制
- 提供日志回调接口
接口定义¶
WebSocket模块的主要接口定义在SOUI/include/interface/ws-i.h文件中,包括:
IWebsocket:WebSocket模块的主接口,用于创建WebSocket客户端和服务器IWsClient:WebSocket客户端接口,用于连接服务器和发送/接收数据IWsServer:WebSocket服务器接口,用于启动服务器和处理客户端连接IConnListener:客户端连接监听器,用于处理连接事件ISvrListener:服务器连接监听器,用于处理服务器事件
使用示例¶
WebSocket客户端使用示例¶
以下是WebSocket客户端的基本使用步骤:
- 创建WebSocket模块实例
- 创建连接监听器
- 创建WebSocket客户端
- 连接到服务器
- 发送和接收数据
- 断开连接
示例代码¶
// 1. 创建WebSocket模块实例
SAutoRefPtr<IWebsocket> websocket;
m_comLoader.CreateInstance(_T("ws"), (IObjRef**)&websocket);
// 2. 创建连接监听器
class MyConnListener : public TObjRefImpl<IConnListener> {
public:
STDMETHOD_(void, onConnected)(CTHIS) OVERRIDE {
// 连接成功处理
}
STDMETHOD_(void, onConnError)(CTHIS_ const char *errStr) OVERRIDE {
// 连接错误处理
}
STDMETHOD_(void, onDisconnect)(CTHIS) OVERRIDE {
// 断开连接处理
}
STDMETHOD_(void, onDataSent)(CTHIS_ int nMsgId) OVERRIDE {
// 数据发送完成处理
}
STDMETHOD_(void, onDataRecv)(CTHIS_ const void *data, int len, BOOL bBinary) OVERRIDE {
// 数据接收处理
}
};
SAutoRefPtr<MyConnListener> listener = new MyConnListener();
// 3. 创建WebSocket客户端
SAutoRefPtr<IWsClient> wsClient;
wsClient = websocket->CreateWsClient(listener);
// 4. 连接到服务器
ClientOption option = { FALSE, NULL, TRUE, TRUE, TRUE }; // 非安全连接
int ret = wsClient->connectTo("127.0.0.1", "/", 8080, "", option);
// 5. 发送数据
const char* textData = "Hello WebSocket!";
wsClient->sendText(textData);
const char* binaryData = "Binary data";
wsClient->sendBinary(binaryData, strlen(binaryData));
// 6. 断开连接
wsClient->disconnect();
WebSocket服务器使用示例¶
以下是WebSocket服务器的基本使用步骤:
- 创建WebSocket模块实例
- 创建服务器监听器
- 创建WebSocket服务器
- 启动服务器
- 处理客户端连接和数据
- 停止服务器
示例代码¶
// 1. 创建WebSocket模块实例
SAutoRefPtr<IWebsocket> websocket;
m_comLoader.CreateInstance(_T("ws"), (IObjRef**)&websocket);
// 2. 创建服务器监听器
class MySvrListener : public TObjRefImpl<ISvrListener> {
public:
STDMETHOD_(BOOL, onConnected)(CTHIS_ ISvrConnection * pConn, const char *uriPath, const char *uriArgs) OVERRIDE {
// 客户端连接处理
return TRUE; // 允许连接
}
STDMETHOD_(void, onConnError)(CTHIS_ ISvrConnection * pConn, const char *errStr) OVERRIDE {
// 连接错误处理
}
STDMETHOD_(void, onDisconnect)(CTHIS_ ISvrConnection * pConn) OVERRIDE {
// 客户端断开连接处理
}
STDMETHOD_(void, onDataSent)(CTHIS_ ISvrConnection * pConn, int nMsgId) OVERRIDE {
// 数据发送完成处理
}
STDMETHOD_(void, onDataRecv)(CTHIS_ ISvrConnection * pConn, const void *data, int len, BOOL bBinary) OVERRIDE {
// 数据接收处理
// 回复客户端
pConn->sendText("Received your message!");
}
};
SAutoRefPtr<MySvrListener> listener = new MySvrListener();
// 3. 创建WebSocket服务器
SAutoRefPtr<IWsServer> wsServer;
wsServer = websocket->CreateWsServer(listener);
// 4. 启动服务器
SvrOption option = { FALSE, NULL, NULL }; // 非安全连接
SvrPingCfg pingCfg = { 30, 60, 3 }; // 30秒发送一次ping,60秒心跳超时,最多3次ping超时
int ret = wsServer->start(8080, "", option, pingCfg);
// 5. 等待服务器运行
wsServer->wait(0); // 无限等待
// 6. 停止服务器
wsServer->quit();
实际应用案例¶
WebSocket模块在games目录下的3个棋牌游戏中得到了实际应用:
1. 中国象棋游戏 (cnchess)¶
中国象棋游戏使用WebSocket模块实现了客户端与服务器之间的实时通信,包括:
- 游戏房间管理
- 玩家匹配
- 游戏状态同步
- 聊天功能
关键实现文件: - games/cnchess/client/WebSocketClient.cpp:WebSocket客户端实现 - games/cnchess/server/WebSocketGame.cpp:WebSocket服务器实现
2. 军棋游戏 (junqi)¶
军棋游戏使用WebSocket模块实现了类似的功能:
- 游戏房间管理
- 玩家匹配
- 游戏状态同步
- 聊天功能
关键实现文件: - games/junqi/client/WebSocketClient.cpp:WebSocket客户端实现 - games/junqi/server/WebSocketGame.cpp:WebSocket服务器实现
3. 升级游戏 (upgrade)¶
升级游戏同样使用WebSocket模块实现了网络通信:
- 游戏房间管理
- 玩家匹配
- 游戏状态同步
- 聊天功能
关键实现文件: - games/upgrade/client/WebSocketClient.cpp:WebSocket客户端实现 - games/upgrade/server/WebSocketGame.cpp:WebSocket服务器实现
配置选项¶
客户端配置选项¶
typedef struct _ClientOption
{
BOOL bSecure; // 是否使用TLS安全连接
const char *ca_u8; // CA证书
BOOL allowSelfSigned; // 是否允许自签名证书
BOOL skipServerCertHostnameCheck; // 是否跳过服务器证书主机名检查
BOOL allowExpired; // 是否允许过期证书
} ClientOption;
服务器配置选项¶
typedef struct _SvrOption
{
BOOL bSecure; // 是否使用TLS安全连接
const char *cert_u8; // 服务器证书
const char *priv_key_u8; // 服务器私钥
} SvrOption;
服务器心跳配置¶
typedef struct _SvrPingCfg
{
uint32_t pingIntervalSeconds; // ping发送间隔时间,单位秒
uint32_t nHeartbeatSeconds; // 心跳超时时间,单位秒
uint32_t nPingTimeoutCount; // ping超时最大次数
} SvrPingCfg;
日志功能¶
WebSocket模块提供了日志回调接口,可以通过以下方式设置日志回调:
websocket->SetLogCallback([](int level, const char *line) {
// 处理日志信息
switch (level) {
case LOG_LEVEL_ERROR:
// 错误日志处理
break;
case LOG_LEVEL_WARN:
// 警告日志处理
break;
case LOG_LEVEL_INFO:
// 信息日志处理
break;
case LOG_LEVEL_DEBUG:
// 调试日志处理
break;
}
});
注意事项¶
- WebSocket模块需要链接WebSocket库(libwebsockets)
- 确保在程序退出前正确释放所有WebSocket资源
- 对于长时间运行的应用,建议使用心跳机制保持连接
- 在TLS模式下,需要正确配置证书和私钥
模块加载和使用¶
WebSocket模块采用了类COM接口设计,所有扩展模块都通过SComLoader直接从DLL加载,不需要在编译时链接模块库。使用步骤如下:
- 确保ws.dll文件在应用程序的搜索路径中
- 使用SComLoader创建模块实例
- 通过接口调用模块功能
示例代码¶
// 1. 包含必要的头文件
#include <helper/com-loader.hpp>
#include <interface/ws-i.h>
// 2. 创建SComLoader实例
SComLoader comLoader;
// 3. 使用SComLoader加载并创建WebSocket模块实例
SAutoRefPtr<IWebsocket> websocket;
if (comLoader.CreateInstance(_T("ws"), (IObjRef**)&websocket) == S_OK) {
// 4. 使用WebSocket模块功能
// 创建客户端、连接服务器等...
}
总结¶
WebSocket模块是SOUI4提供的一个功能完整的WebSocket通信库,适用于各种需要实时双向通信的应用场景。通过该模块,开发者可以快速实现WebSocket客户端和服务器,支持文本和二进制数据传输,以及TLS安全连接。
在实际应用中,WebSocket模块已经在3个棋牌游戏中得到了验证,能够稳定处理大量并发连接和实时数据传输。