Go 服务端 SDK Demo 运行指南
这是使用 drim.Client 的单进程 Web 聊天示例:Go 后端调用服务端 SDK,接收签名回调,再通过 WebSocket 向页面推送。 前端为内嵌的原生 ES 模块,不需要 Node.js、前端构建工具或额外的 Go 依赖。
与客户端 Demo 的区别
| 项目 | 本页的服务端 Demo | 客户端 Demo |
|---|---|---|
| 源码目录 | sdk/server/go/demo | sdk/go/demo |
| SDK 包名 | drim | im |
| Go 版本 | 1.23 或以上 | 1.26.5 或以上 |
| 应用配置 | IM 地址、AppKey、Client ID / Client Secret | IM 地址和 AppKey |
| 用户身份 | 设备 User Token 由后端设备适配层保存 | 每个浏览器会话持有一个用户客户端 |
| 实时更新 | 已验证的签名回调 → Demo → 浏览器 | IM 用户长连接 → Demo → 浏览器 |
| 默认端口 | 127.0.0.1:8092 | :8090 |
应用 SDK 负责用户、好友、群和消息等业务管理操作。用户历史、用户撤回与改密通过 Demo 的设备接口完成,不扩展服务端 SDK 的公共 API。 两套 Demo 都使用 demo_sid Cookie,体验时请使用独立浏览器或无痕上下文,不能靠不同端口隔离登录。
准备
- 下载服务端 SDK + Demo ZIP,校验并完整解压。已有 IM 仓库也可直接使用。
- 准备可达的 IM 服务地址,以及同一应用的 AppKey、Client ID / Client Secret。
- 创建该应用下的两个测试账号,或使用 Demo 注册入口;密码登录需符合应用策略。
- 配置下面的实时回调。没有回调时可访问页面和调用接口,但不能用来验收对端实时更新。
需要本机 IM 测试服务时,使用完整 IM 仓库(SDK 压缩包不包含服务端及基础设施)。在仓库根目录使用独立 harness:
make infra-up
go build -o /tmp/im-harness ./sdk/conformance/harness
/tmp/im-harness -env .env -addr 127.0.0.1:18880 -control 127.0.0.1:18890 \
-db im_go_demo_test -redis-prefix go-demo-test:harness 的 GET /env 和 GET /credentials 提供本次应用配置,控制接口只用于本机开发。 连接已部署的 IM 时直接使用控制台中的应用配置,不需要启动 harness。
启动
下载服务端 SDK + Demo ZIP · SHA256 校验文件
解压后进入 deeprespond-im-server-go-sdk-1.0.0-dev。在终端设置应用凭据,再进入 SDK 子模块:
export IM_CLIENT_ID='替换为应用的 Client ID'
export IM_CLIENT_SECRET='替换为应用的 Client Secret'
cd sdk/server/go
go run ./demo \
--api http://127.0.0.1:18880 \
--app-key '组织#应用' \
--addr 127.0.0.1:8092 \
--callback-credentials '地址ID:回调密钥'打开 http://127.0.0.1:8092,用同一应用下的账号登录;另一个浏览器上下文登录第二个账号。 在 SDK 模块目录执行 go build -o im-go-server-demo ./demo 可以生成内嵌页面的二进制,再使用同样的参数运行。 Windows 构建时使用输出名 im-go-server-demo.exe。
| 参数 | 默认值或环境变量 | 说明 |
|---|---|---|
--api | http://127.0.0.1:18480 | IM 服务地址;使用上面的 harness 时显式改为 18880 |
--app-key | APP_KEY | 组织#应用 |
--client-id | IM_CLIENT_ID | 应用 Client ID |
--client-secret | IM_CLIENT_SECRET | 同一应用的 Client Secret |
--addr | 127.0.0.1:8092 | 浏览器访问 Demo 的监听地址 |
--callback-credentials | 无 | endpoint_id:secret,多个用逗号分隔 |
--debug | 关闭 | SDK 调试日志 |
配置实时回调
依次完成创建、启动和验证,避免在 Demo 尚未监听时验证失败:
- 在应用控制台创建回调地址,指向 Demo 的
/im/callback,保存地址 ID 和密钥。 - 将 ID 和密钥填入
--callback-credentials,启动 Demo。SDK 处理签名和 URL 验证请求。 - 在控制台验证地址,确认验证成功后启用事件订阅。
需要订阅的事件:
message.sent, message.recalled, message.edited
friend.added, friend.removed, friend.updated, friend_request.received, blacklist.changed
group.created, group.info_changed, group.dismissed
group.members_added, group.members_removed, group.members_updated
user.profile_changed, user.sessions_revoked, user.relogin_required, presence.changed同时开启 filters.message_include_tips=true,推荐批量大小 10、超时 5000 毫秒。 本机 harness 允许 http://127.0.0.1:8092/im/callback;其他环境使用 IM 服务能访问的回调地址,并遵循地址配置规则。 回调请求由 IM 服务发起,浏览器能打开 Demo 不代表 IM 能访问它。 本机通过 harness 控制接口创建地址、验证地址的请求结构见 Demo README。
验证与能力边界
双账号登录后,依次验证单聊、群聊、文本/图片/文件、引用回复、历史翻页、已读、删除/清空、撤回、资料变化、设备吊销和退出登录。
- 每个页面动作先核对真实设备会话;群成员与管理角色重新从服务端读取。
- 用户历史应用逐用户删除、清空与入退群边界;应用 SDK 的管理历史不能直接展示给用户。
- 用户撤回校验发送者、角色和撤回窗口;密码修改校验旧密码并保留当前设备。
- 退出登录吊销真实设备;旧吊销回调不会直接结束之后建立的新登录。
- 附件仅内联按字节识别的 PNG/JPEG/GIF/WebP,其余强制下载,并设置
nosniff、沙箱 CSP 和禁止缓存。
正在输入只在本进程转发;会话和缓存保存在内存中,重启后重新登录。 回应、会话置顶、好友申请及群邀请的接受/拒绝没有由本示例的服务端 OpenAPI 提供,界面会提示;需要这些用户能力时使用客户端 SDK。 业务中的管理授权和附件代理要求见调用接口。
文件组织
| 模块 | 职责 |
|---|---|
main.go、http.go、media.go | 启动、路由、注册登录及附件 |
bridge.go、wsbridge.go | 浏览器连接与 WebSocket 帧 |
state.go、views.go | 状态与独立响应快照 |
device.go、data.go | 真实设备接口、列表及权限 |
actions*.go、messages.go | 动作分发、业务操作及发送 |
callbacks.go、push.go、sessions.go、message_events.go | 回调同步、页面推送及会话清理 |
web/、*_test.go、testdata/ | 原生页面模块、单元/并发与截图 E2E |
源码文件保持 500 行以内;共享状态由互斥锁保护,网络调用在锁外执行。此限制由 Demo 结构测试检查。
测试与排查
压缩包内的 SDK 和 Demo 单元测试可直接执行:
cd sdk/server/go
go test ./...下面的生成检查、真实集成和 E2E 需要完整 IM 仓库和独立测试应用;在仓库根目录执行:
make sdk-server-go-test
IM_TEST_HARNESS=http://127.0.0.1:18890 make sdk-server-go-integration安全回归和双视口截图脚本的环境变量及运行方式见 Demo README。安全回归会吊销测试应用的旧会话,与浏览器 E2E 分开运行。
| 现象 | 检查 |
|---|---|
| 缺少应用凭据 | 参数或环境变量是否齐全,是否与 AppKey 属于同一应用 |
| 登录失败 | 账号、密码、应用状态及密码登录策略 |
| 回调验证失败 | /im/callback 的可达性、地址 ID、密钥与反向代理路径 |
| 能发送但对方不更新 | 地址是否已验证、事件订阅及密钥是否正确 |
| 浏览器登录互相覆盖 | 改用独立浏览器上下文,Cookie 不按端口隔离 |
| 重启后丢失登录 | 本示例使用内存状态,重新登录即可 |
