Go server SDK demo guide
This is a single-process web chat example built with drim.Client: the Go back end calls the server SDK, receives signed callbacks, and pushes them to the page over WebSocket. The front end is embedded native ES modules, needing no Node.js, front-end build tools or extra Go dependencies.
How it differs from the client demo
| This server demo | Client demo | |
|---|---|---|
| Source directory | demo/ | demo/ |
| SDK package | drim | im |
| Go version | 1.23 or later | 1.26.5 or later |
| App config | IM address, AppKey, Client ID and Client Secret | IM address and AppKey |
| User identity | The demo back end keeps the user's sign-in token (User Token) on their behalf | Each browser session holds a user client |
| Live updates | Signed callbacks from IM, verified by the demo, then pushed to the browser | The user's persistent connection → demo → browser |
| Default port | 127.0.0.1:8092 | :8090 |
The server SDK handles management operations on users, friends, groups and messages. The chat history users see, users recalling their own messages and changing their password are done by the demo calling client APIs as the user; they aren't part of the server SDK's public API. Both demos use a cookie named demo_sid, and cookies aren't separated by port, so use different browsers or a private window when trying both.
Before you start
- Download the server SDK + demo ZIP, verify it and unzip it completely. Start from the unzipped module root; with the full IM repository, go into
sdk/server/gofirst. - Have a reachable IM service address, plus the AppKey, Client ID and Client Secret of the same app.
- Create two test accounts in the app, or use the demo's sign-up; password sign-in must be allowed by the app's policies.
- Configure the live callbacks below. Without callbacks you can still open the page and call APIs, but the other person's messages won't appear live.
To run an IM test service on your own machine, use the full IM repository (the SDK zip has no server or infrastructure) and start the test service (harness) from the repository root:
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:The test service's GET /env and GET /credentials return the app config it created, and its control API is for local development only. When connecting to a deployed IM service, use the app config from the console instead; there's no need to start the test service.
Start
Download the server SDK + demo ZIP · SHA256 checksums
Unzip it, go into deeprespond-im-server-go-sdk-1.0.3, set the app credentials, and run from that directory:
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:回调密钥'Open http://127.0.0.1:8092 and sign in with an account of the same app; sign in as the second account in another browser (or a private window). Run go build -o im-go-server-demo ./demo in the SDK module directory to build a binary with the page embedded, and run it with the same flags; on Windows, name the output im-go-server-demo.exe.
| Flag | Default or environment variable | Description |
|---|---|---|
--api | http://127.0.0.1:18480 | IM service address; with the local test service above, use port 18880 |
--app-key | APP_KEY | org#app |
--client-id | IM_CLIENT_ID | The app's Client ID |
--client-secret | IM_CLIENT_SECRET | The same app's Client Secret |
--addr | 127.0.0.1:8092 | Address the demo listens on for the browser |
--callback-credentials | None | endpointID:secret, comma-separated for several |
--debug | Off | Print SDK debug logs |
Configure live callbacks
Create, start and verify in this order, so verification doesn't fail before the demo is listening:
- In the console, create a callback endpoint for the app pointing to the demo's
/im/callback, and save the endpoint ID and secret. - Put the endpoint ID and secret in
--callback-credentialsand start the demo. The SDK handles signature checks and URL verification. - Verify the endpoint in the console, and once it succeeds, turn on event subscriptions.
Events to subscribe to:
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.changedAlso turn on filters.message_include_tips=true; a batch size of 10 events and a 5000-millisecond timeout are recommended. The local test service allows callbacks to http://127.0.0.1:8092/im/callback; elsewhere, use an address the IM service can reach, following the endpoint rules. Callbacks come from the IM service, so the browser being able to open the demo doesn't mean the IM service can reach it. For the request format to create and verify endpoints through the local test service's control API, see the demo README.
What to try and what it checks
After signing in with two accounts, try one-to-one chat, group chat, text, images and files, quote replies, scrolling back through history, read status, delete and clear, recall, profile changes, revoking devices, and signing out.
The demo's back end does the checks below, and your own service needs them too:
- Every action from the page first checks the user's real sign-in session; group membership and admin roles are read again from the server each time.
- Chat history shown to a user must be filtered for that user (messages they deleted or cleared, messages from before they joined or after they left a group). The server SDK reads the full admin view, which mustn't be shown to users directly.
- When users recall messages, check the sender, role and recall time limit; when they change their password, verify the old one and keep the current device signed in.
- Signing out revokes the real device sign-in; an earlier revocation callback never ends a sign-in made after it.
- Attachments are only shown inline when their content is recognized as PNG, JPEG, GIF or WebP; everything else is sent as a download, with
nosniff, a sandboxed CSP and no caching.
Typing indicators are only relayed within the demo process; sessions and caches live in memory, so users sign in again after a restart. Reactions, pinning conversations, and accepting or declining friend requests and group invitations aren't in the server OpenAPI, so the UI says so; use a client SDK for those. For the permission checks and attachment proxying your service needs, see Calling the API.
File layout
| Module | Responsibility |
|---|---|
main.go, http.go, media.go | Startup, routing, sign-up and sign-in, attachments |
bridge.go, wsbridge.go | Browser connections and WebSocket messages |
state.go, views.go | State and the data returned to the page |
device.go, data.go | APIs called as the user, lists and permissions |
actions*.go, messages.go | Dispatching page actions, business operations and sending messages |
callbacks.go, push.go, sessions.go, message_events.go | Handling callbacks, pushing to the page, cleaning up sessions |
web/, *_test.go, testdata/ | Page modules; unit tests, concurrency tests and screenshot end-to-end tests |
Every source file stays under 500 lines; shared state is protected by mutexes, and network calls happen outside locks. The demo's structure tests check these rules.
Testing and troubleshooting
The SDK and demo unit tests in the zip run as is:
go test ./...The generation checks, real integration tests and end-to-end tests below need the full IM repository and a separate test app; run them from the repository root:
make sdk-server-go-test
IM_TEST_HARNESS=http://127.0.0.1:18890 make sdk-server-go-integrationFor the environment variables and how to run the security regression tests and screenshot scripts, see the demo README. The security regression tests revoke the test app's existing sign-ins, so don't run them at the same time as the browser end-to-end tests.
| Symptom | Check |
|---|---|
| App credentials reported missing | Whether all flags or environment variables are set, and belong to the same app as the AppKey |
| Sign-in fails | The account, password, app status, and whether password sign-in is allowed |
| Endpoint verification fails | Whether the IM service can reach /im/callback, and whether the endpoint ID, secret and reverse proxy path are right |
| Sending works but the other page doesn't update | Whether the endpoint is verified, events are subscribed, and the secret is right |
| Sign-ins in two browser windows overwrite each other | Use different browsers or a private window; cookies aren't separated by port |
| Signed out after a restart | This example keeps state in memory only; just sign in again |
