Go 服务端 SDK Demo 运行指南
这是一个用 drim.Client 写的单进程 Web 聊天示例:Go 后端调用服务端 SDK,接收带签名的回调,再通过 WebSocket 推送给页面。 前端是内嵌的原生 ES 模块,不需要 Node.js、前端构建工具或额外的 Go 依赖。
与客户端 Demo 的区别
| 项目 | 本页的服务端 Demo | 客户端 Demo |
|---|---|---|
| 源码目录 | demo/ | demo/ |
| SDK 包名 | drim | im |
| Go 版本 | 1.23 或以上 | 1.26.5 或以上 |
| 应用配置 | IM 地址、AppKey、Client ID 和 Client Secret | IM 地址和 AppKey |
| 用户身份 | 用户的登录令牌(User Token)由 Demo 后端代为保存 | 每个浏览器会话持有一个用户客户端 |
| 实时更新 | IM 发来的签名回调经 Demo 校验后推给浏览器 | 用户的长连接 → Demo → 浏览器 |
| 默认端口 | 127.0.0.1:8092 | :8090 |
服务端 SDK 负责用户、好友、群和消息等管理操作。用户看到的聊天记录、用户自己撤回消息和修改密码,由 Demo 以用户的身份调用客户端接口完成,不属于服务端 SDK 的公开 API。 两个 Demo 都使用名为 demo_sid 的 Cookie,Cookie 不按端口区分,所以同时体验时请使用不同的浏览器或无痕窗口。
准备
- 下载服务端 SDK + Demo ZIP,校验后完整解压。从解压后的模块根目录启动;使用完整的 IM 仓库时先进入
sdk/server/go。 - 准备可访问的 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:测试服务的 GET /env 和 GET /credentials 返回这次创建的应用配置,它的控制接口只用于本机开发。 连接已部署的 IM 时,直接使用控制台中的应用配置,不需要启动测试服务。
启动
下载服务端 SDK + Demo ZIP · SHA256 校验文件
解压后进入 deeprespond-im-server-go-sdk-1.0.3,设置应用的凭据,在这个目录中运行:
export IM_CLIENT_ID='替换为应用的 Client ID'
export IM_CLIENT_SECRET='替换为应用的 Client Secret'
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 服务地址;使用上面的本机测试服务时改为 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 | 无 | 地址ID:密钥,多个用逗号分隔 |
--debug | 关闭 | 输出 SDK 的调试日志 |
配置实时回调
按顺序创建、启动、验证,以免 Demo 还没有开始监听时验证失败:
- 在控制台中为应用创建回调地址,指向 Demo 的
/im/callback,保存地址 ID 和密钥。 - 把地址 ID 和密钥填入
--callback-credentials,启动 Demo。签名校验和 URL 验证由 SDK 处理。 - 在控制台中验证地址,验证成功后开启事件订阅。
需要订阅的事件:
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 毫秒。 本机测试服务允许回调到 http://127.0.0.1:8092/im/callback;其他环境要使用 IM 服务能访问到的地址,规则见回调地址的配置。 回调由 IM 服务发起,浏览器能打开 Demo 不代表 IM 服务能访问它。 用本机测试服务的控制接口创建和验证地址的请求格式,见 Demo README。
验证与能力边界
用两个账号登录后,依次试单聊、群聊、文本/图片/文件、引用回复、翻看历史、已读、删除和清空、撤回、资料变化、吊销设备和退出登录。
Demo 在后端做了下面这些检查,你的业务也需要:
- 页面上的每个操作,先核对用户真实的登录会话;群成员和管理员角色每次都从服务端重新读取。
- 用户看到的聊天记录要按用户过滤(各自删除、清空的消息,入群前、退群后的消息);服务端 SDK 读到的是管理视角的全部记录,不能直接给用户看。
- 用户撤回消息时检查发送者、角色和撤回时限;修改密码时校验旧密码,并保留当前设备的登录。
- 退出登录时吊销真实的设备登录;之前的吊销回调不会结束之后新建立的登录。
- 附件只有按文件内容识别为 PNG、JPEG、GIF、WebP 的直接显示,其他一律作为下载,并设置
nosniff、沙箱 CSP 和禁止缓存。
“正在输入”只在 Demo 进程内转发;会话和缓存保存在内存中,重启后要重新登录。 表情回应、会话置顶、接受或拒绝好友申请和群邀请不在服务端 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/ | 页面模块;单元测试、并发测试和截图端到端测试 |
每个源码文件不超过 500 行;共享状态用互斥锁保护,网络调用在锁外执行。Demo 的结构测试会检查这些规则。
测试与排查
压缩包中的 SDK 和 Demo 单元测试可以直接运行:
go test ./...下面的生成检查、真实集成测试和端到端测试需要完整的 IM 仓库和单独的测试应用,在仓库根目录执行:
make sdk-server-go-test
IM_TEST_HARNESS=http://127.0.0.1:18890 make sdk-server-go-integration安全回归测试和截图脚本的环境变量与运行方式见 Demo README。安全回归测试会吊销测试应用中已有的登录,请不要和浏览器端到端测试同时运行。
| 现象 | 检查 |
|---|---|
| 提示缺少应用凭据 | 参数或环境变量是否齐全,是否和 AppKey 属于同一个应用 |
| 登录失败 | 账号、密码、应用的状态,以及是否允许密码登录 |
| 回调地址验证失败 | /im/callback 能否从 IM 服务访问,地址 ID、密钥和反向代理的路径是否正确 |
| 能发送,但对方的页面不更新 | 地址是否已经验证,事件是否已订阅,密钥是否正确 |
| 两个浏览器窗口的登录互相覆盖 | 改用不同的浏览器或无痕窗口;Cookie 不按端口区分 |
| 重启后要重新登录 | 这个示例的状态只在内存中,重新登录即可 |
