WuKongIM Docs

C# 快速接入

使用 WuKongEasySDK-CSharp NuGet 正式包接入 .NET 8,完成认证、在线消息、自动重连和异步释放。

编辑此页报告文档问题

WuKongEasySDK-CSharp 参考 JavaScript EasySDK 的 WebSocket JSON-RPC 协议,提供符合 C# 习惯的异步 API 和强类型事件。运行时不依赖第三方包。

NuGet 正式版 1.0.0

WuKongEasySDK 1.0.0 已发布到 nuget.org,对应源码 02ea7d60cd94feef1996f41bca35ffc3b8e18ea6。下文默认使用公共 NuGet 安装;源码引用与本地打包用于需要自行构建的场景。

开始前

  • 准备 .NET 8 或更新版本,以及 Windows、Linux 或 macOS 开发环境。当前目标框架为 net8.0,不包含 Unity、.NET Framework 和浏览器 WebAssembly 支持。
  • 启动 /readyz 健康的 WuKongIM 单节点集群或多节点集群,确认客户端可以访问 WebSocket Gateway。单节点集群同样遵循集群语义,默认使用 256 Hash Slots。
  • 业务后端为 Alice 和 Bob 分别返回 uidtokenwebsocketUrl。客户端不调用 /user/token/route 等 Product HTTP 管理接口。
  • C# 默认使用 PC/Desktop 2。后端签发 Token 的 device_flag 必须与客户端一致;APP 为 0,Web 为 1

先阅读 身份与 Token。生产环境使用 HTTPS/WSS,不关闭证书验证,不把 Token 放入 URL、日志或源码。

1. 安装 NuGet 正式包

dotnet new console -n MyChat --framework net8.0
dotnet add MyChat/MyChat.csproj package WuKongEasySDK --version 1.0.0 --source https://api.nuget.org/v3/index.json

可选:从固定源码构建

git clone https://github.com/WuKongIM/WuKongEasySDK-CSharp.git
git -C WuKongEasySDK-CSharp checkout 02ea7d60cd94feef1996f41bca35ffc3b8e18ea6
dotnet new console -n MyChat --framework net8.0
dotnet add MyChat/MyChat.csproj reference WuKongEasySDK-CSharp/src/WuKongEasySDK/WuKongEasySDK.csproj

两个目录处于同一级。将确切源码 revision 记录到构建配置,或通过固定 commit 的子模块维护引用。

如需本地 NuGet 安装,先在这个固定 checkout 中生成包:

cd WuKongEasySDK-CSharp
dotnet pack src/WuKongEasySDK -c Release -o artifacts
dotnet add ../MyChat/MyChat.csproj package WuKongEasySDK --version 1.0.0 --source ./artifacts

公共包、项目引用和本地包三选一,不要同时引用。此处的 --source ./artifacts 指向你刚生成的本地源。

2. 由业务后端提供连接材料

登录业务系统后,通过受保护的业务接口取得:

{
  "uid": "alice",
  "token": "backend-issued-desktop-token",
  "websocketUrl": "wss://im.example.com/ws"
}

下面的控制台示例从 WUKONGIM_WS_URLWUKONGIM_UIDWUKONGIM_TOKEN 环境变量读取这些值;桌面应用可以改为读取登录响应。它们是本示例的变量,不是服务端的 WK_ 配置项。

3. 连接、监听并发送

用下面代码替换 MyChat/Program.cs。启动前设置当前账号的三个环境变量,通过命令行参数传入对方 UID。

using WuKongEasySDK;

static string Required(string name) =>
    Environment.GetEnvironmentVariable(name)
    ?? throw new InvalidOperationException($"Missing {name}");

if (args.Length != 1)
    throw new ArgumentException("Pass the peer UID as the first argument.");

await using var im = new WKIM(Required("WUKONGIM_WS_URL"), new AuthOptions
{
    Uid = Required("WUKONGIM_UID"),
    Token = Required("WUKONGIM_TOKEN"),
    DeviceFlag = DeviceFlag.Desktop
}, new WKIMOptions
{
    ConnectTimeout = TimeSpan.FromSeconds(10),
    RequestTimeout = TimeSpan.FromSeconds(15)
});

Action<RecvMessage> onMessage = message =>
{
    // 按 MessageId 去重,并把 Payload 交给应用状态。
    // WinForms/WPF 等 UI 需切回 UI 线程;不要打印完整消息。
    Console.WriteLine("Message received.");
};
im.Message += onMessage;
im.Connected += _ => Console.WriteLine("Connected.");
im.Disconnected += _ => Console.WriteLine("Disconnected.");
im.Error += _ => Console.WriteLine("SDK operation failed.");
im.CustomEvent += notification =>
{
    // 按 notification.Type 分发 notification.Data。
};

try
{
    await im.ConnectAsync();
    Console.WriteLine("Start the peer, then press Enter to send.");
    Console.ReadLine();
    var result = await im.SendAsync(args[0], ChannelType.Person,
        new { type = 1, content = "Hello from C# 👋" });
    if (!result.IsSuccess)
        Console.WriteLine($"SEND rejected: {(int)result.ReasonCode}");
    else
        Console.WriteLine("Server accepted SEND.");
    Console.WriteLine("Press Enter after checking both directions to exit.");
    Console.ReadLine();
}
finally
{
    im.Message -= onMessage;
    await im.DisconnectAsync();
}

两个终端分别使用 Alice/Bob 的连接材料,运行 dotnet run --project MyChat -- bobdotnet run --project MyChat -- alice。异常会通过异步方法返回给调用者,后台错误也会触发 Error;应用应为认证失败、超时和业务拒绝分别提供处理界面。

库默认没有日志。只有显式设置 WKIMOptions.DebugLogger 才输出固定运行状态文本,不包含 Token、Payload、原始帧或服务端错误正文。

4. 群聊、发送结果与接收数据

群聊使用 ChannelType.Group 和业务后端管理的群 ID;成员关系和权限仍由服务端判定。可传入 SendOptions 设置 ClientMsgNoHeaderSettingTopic。默认 Header 为 RedDot = true,显式传入的 Header 不会被 SDK 覆盖。

ReasonCode.Success1SendResult.IsSuccess 表示服务端接受了发送,不代表 Bob 已收到、已展示或已读。128–255 等业务拒绝码保留在结果中;JSON-RPC 错误抛出 WKIMRpcException,通过数字 Code 判定。

消息 ID 使用 string,数字形式的 ID 不经过浮点转换。MessageSeqNodeIdulong。消息 Timestamp 单位为 Unix ,自定义事件 Timestamp 为 Unix 毫秒

RecvMessage.PayloadEventNotification.Data 为拥有独立生命周期的 JsonElement。接收 Payload 支持 JSON 对象和 Base64 JSON;无法解码的字符串保留原值。自定义事件的 JSON 字符串会解析为 JSON 值,普通字符串保持不变。

5. 重连、取消与释放

行为C# SDK 约定
实例所有权new WKIM / WKIM.Init 创建独立实例,无隐式全局单例
并发连接多个 ConnectAsync 共享尝试;取消某个调用只停止其等待
停止共享连接等待 DisconnectAsync 后才再次连接
初次失败建连与认证共用 10 秒预算,失败直接返回
已连接后断线默认最多重试 5 次,间隔 1、2、4、8、16 秒;成功后重置
停止自动重连认证拒绝、服务端断开/踢下线、主动断开或释放
最终清理在应用生命周期代码中等待 DisposeAsync,或使用 await using

Token 更新或账号切换时,释放旧实例,再使用新的业务凭据创建客户端。需要跨进程保留设备 ID 时显式设置 AuthOptions.DeviceId

事件在后台按顺序派发,回调必须尽快返回,不应阻塞等待 SDK 的异步操作或在回调内等待释放。单个监听器抛异常不会中断其他监听器和自动 ACK。已经入队的回调可能在移除监听或断开后继续执行;DisposeAsync 会等待它们结束。

RECVACK 表示消息进入 SDK 接收队列,不是业务处理确认。默认最多保留 256 个待完成请求、128 个待派发事件,单个完整 JSON-RPC 帧上限为 1 MiB。请求超限抛出 WKIMBackpressureException;事件队列满会关闭连接,不确认无法入队的消息。应用可以通过 WKIMOptions 调整这些边界。

SDK 不缓存离线消息,也不自动重发 SEND。请求超时、取消或断线时,发送可能已经成功。应用应先核对业务状态,需要重试同一条逻辑消息时复用 SendOptions.ClientMsgNo。离线恢复、会话、未读数、推送与业务回执由应用自行维护。

6. 运行官方示例和验收

在固定源码目录执行:

dotnet build -c Release
dotnet test -c Release
dotnet run --project examples/ConsoleChat -- bob

控制台示例使用同样的环境变量,输入文本发送,/quit 或 Ctrl+C 退出。它把正文显示为聊天界面内容,不输出完整协议对象。

已有服务端二进制时,还可运行自动化真实进程测试:

WUKONGIM_BINARY=/absolute/path/to/wukongim python3 scripts/smoke.py

该脚本只启动和清理自己拥有的回环地址单节点集群,使用 256 Hash Slots 并启用 Token 认证。它自动准备两个测试账号,检查双向 Unicode 消息的 SENDACK/RECV 一致性、重连、心跳和错误 Token 拒绝。

原始实现 d365a354f5e0f25fbd7f83bb59aa365ba43e899f 在 macOS arm64、.NET SDK 8.0.424 / runtime 8.0.30 通过 35 项测试、Release 构建与本地 NuGet 打包,并对 WuKongIM 132e46209d98fa0425cc0f88e7a97080cdad044d 完成上述真实进程验证。自定义事件与故障重连由回环 WebSocket 测试覆盖。此记录不包含公共 NuGet 下载、生产 WSS、离线恢复、多节点容量或长期稳定性验证。

NuGet 1.0.0独立发布验证覆盖 Windows、Linux、macOS 构建、35 项 SDK 测试、7 项发布校验测试与全新项目本地包安装。发布后从 nuget.org 下载精确版本,比较除 NuGet 签名外的全部包内容与测试产物,并在空包缓存、仅公共源的独立项目中完成还原、编译、加载和释放。此公共安装记录与上述真实服务端通信记录分别保留。

C# / JavaScript 真实互通

早期独立的 C#/JS 互通 CI 分别测试公共 NuGet WuKongEasySDK 1.0.0(空包缓存安装)与当前 C# 源码。固定对端为 npm easyjssdk 2.0.4、Node 24 + ws 8.21.3,服务端为 v3.0.0-beta.9 / 734166e0ec30fc0f6f10fef6f6d1889d079ab636。测试工具源码为 1db387c4f794a45bdb6f4e419d68dbe2bfef740f,与 NuGet 包源码分别记录。

五组场景覆盖双向中文/emoji 与嵌套自定义 Payload、超出 JavaScript 安全整数范围的消息 ID 及 SENDACK/RECV 一致性、错误 Token 拒绝、断网后自动重连、真实服务端崩溃重启,以及主动断开后拒绝离线 SEND 并允许显式重连。该服务端的 SENDACK 不返回 clientMsgNo,测试会校验 RECV 保留原始关联号。

上述早期复现记录的范围为 Node + ws。其中发现的 Node 原生 WebSocket 重连停滞,已在下面的独立源码修复与验收中处理。

Chromium/WSS 与原生 Node 恢复

早期扩展互通 CI分别使用正式 NuGet 1.0.0 和 C# 候选源码,验证 Node 24.3.0 原生 WebSocket,以及 Playwright 1.62.1 驱动的真实 Chromium。服务端仍固定为 734166e0ec30fc0f6f10fef6f6d1889d079ab636,JS 固定为修复源码 5e5dfb727fb0ea08294939962ae799e998b7ca5c。该修复结束只发出 error、没有后续 close 的握手失败,让有限次数重连继续执行;npm easyjssdk 2.0.4 不包含此修复

浏览器从真实 HTTPS 页面建立 WSS 连接,C# 使用原有 ClientWebSocket。测试通过临时 CA 和隔离的浏览器 NSS 信任库保留正常证书校验,要求双方拒绝不受信任的 CA 和主机名不匹配的证书,且没有解密后的应用请求进入服务端协议。证书控制通过后,再执行双向消息、错误 Token、断网恢复、服务端重启和主动断开五组场景。

JS 修复已随 npm easyjssdk 2.0.5 正式发布,对应源码 b6d0bbe822b9c5b6f95a10d55b593d30184414f6公共包互通 CI 从空缓存安装该固定 npm 包,六组正式 NuGet / C# 候选源码与 ws、原生 Node、Chromium WSS 的组合均通过,包含上述证书拒绝控制。

该单节点矩阵运行四条 Linux 任务,产生六份报告,记录 npm 下载地址及 SHA-512、实际测试提交、Chromium 版本和证书控制结果;复现与信任范围说明运行方法。这里验证的是临时 CA、回环 TLS 代理和 Chromium,不代表所有公网 CA、反向代理、Firefox/WebKit、多节点容量或长期稳定性。

三节点集群与应用切换地址

完整三节点故障恢复验收尚未通过,服务端迁移、恢复日志冲突和重启后漏收问题已记录在 Issue #927。本轮只处理 SDK、测试和文档;此前未合并的服务端实验不能作为已发布能力依据。上文已通过的单节点 WS/WSS 验证仍保留各自的精确版本和运行记录。

地址切换由应用负责。 一个 SDK 实例只有一个固定地址,自动重连仍访问该地址。业务后端选择存活入口并取得其 /route,客户端等待旧实例 DisposeAsync 完成,再使用新地址与原有凭据创建实例、注册事件并连接。中断中的 SEND 可能结果未知,不应自动重发已经确认或结果不明的消息。

三节点手动复现工具固定公共 NuGet WuKongEasySDK 1.0.0、npm easyjssdk 2.0.5、Node 24.3.0,服务端使用已发布的 v3.0.0-beta.9 源码 734166e0ec30fc0f6f10fef6f6d1889d079ab636。三个回环进程使用 256 Hash Slots、10 个逻辑 Slot 和三副本;测试覆盖入口间单聊/群聊、断线与离线发送拒绝、应用替换实例、节点重新加入,并严格检查 ACK/RECV 的关联和消息内容。节点上线、ISR 元数据齐全不等于物理副本已经追平。

常规 push/PR CI 运行四条单节点任务,产生六份 WS/原生 Node/Chromium WSS 报告。手动触发时选择 include_cluster=true 才追加两条三节点复现任务;遇到服务端阻塞会正常失败,不计为 SDK 三节点验收通过。本地运行命令为 python3 scripts/interop.py --transport native --topology three-node,候选源码增加 --candidate,并按工具说明提供精确服务端二进制。

复现工具记录服务端默认 90 秒在线路由租期引起的登录延迟,以及显式的迁移扫描预算。对已观察到的登录错误 15 有限重试是复现控制,不是重试所有系统错误或 SEND 的建议。完整三节点恢复、立即切换、多节点 WSS、离线同步、大群容量与长期稳定性均未由该工具建立保证。

下一步

查看 运行官方示例SDK 验证记录,或回到 WuKongEasySDK 比较平台。生产接入继续参考 消息收发集成验收

本页内容