跳转至

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客户端的基本使用步骤:

  1. 创建WebSocket模块实例
  2. 创建连接监听器
  3. 创建WebSocket客户端
  4. 连接到服务器
  5. 发送和接收数据
  6. 断开连接

示例代码

// 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服务器的基本使用步骤:

  1. 创建WebSocket模块实例
  2. 创建服务器监听器
  3. 创建WebSocket服务器
  4. 启动服务器
  5. 处理客户端连接和数据
  6. 停止服务器

示例代码

// 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;
    }
});

注意事项

  1. WebSocket模块需要链接WebSocket库(libwebsockets)
  2. 确保在程序退出前正确释放所有WebSocket资源
  3. 对于长时间运行的应用,建议使用心跳机制保持连接
  4. 在TLS模式下,需要正确配置证书和私钥

模块加载和使用

WebSocket模块采用了类COM接口设计,所有扩展模块都通过SComLoader直接从DLL加载,不需要在编译时链接模块库。使用步骤如下:

  1. 确保ws.dll文件在应用程序的搜索路径中
  2. 使用SComLoader创建模块实例
  3. 通过接口调用模块功能

示例代码

// 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个棋牌游戏中得到了验证,能够稳定处理大量并发连接和实时数据传输。