# WebSocket 协议文档 XuqmGroup IM 使用 **STOMP over WebSocket** 协议进行实时消息通信。 --- ## 连接地址 | 环境 | 地址 | |------|------| | 演示环境 | `wss://dev.xuqinmin.com/ws/im` | | 生产环境 | 由租户平台分配 | 连接时需携带 `token` 参数: ``` wss://dev.xuqinmin.com/ws/im?token={userSig} ``` --- ## 心跳机制 客户端在 STOMP CONNECT 帧中声明心跳: ``` CONNECT accept-version:1.2 heart-beat:0,0 host:dev.xuqinmin.com Authorization:Bearer {token} \x00 ``` > 当前服务端不强制心跳,客户端可依赖 WebSocket 原生 `onclose`/`onerror` 检测断线。 --- ## 消息格式(STOMP) ### CONNECT 帧 客户端建立 WebSocket 连接后,发送 STOMP CONNECT: ``` CONNECT accept-version:1.2 heart-beat:0,0 host:dev.xuqinmin.com Authorization:Bearer {token} \x00 ``` ### CONNECTED 帧 服务端鉴权通过后返回: ``` CONNECTED version:1.2 \x00 ``` ### SUBSCRIBE 帧 订阅个人消息队列(自动执行): ``` SUBSCRIBE id:sub-1 destination:/user/queue/messages \x00 ``` 订阅群消息: ``` SUBSCRIBE id:sub-2 destination:/topic/group/{groupId} \x00 ``` ### SEND 帧 — 发送消息 ``` SEND destination:/app/chat.send content-type:application/json {"appId":"ak_demo_chat","messageId":"...","toId":"user_002","chatType":"SINGLE","msgType":"TEXT","content":"Hello"} \x00 ``` ### SEND 帧 — 撤回消息 ``` SEND destination:/app/chat.revoke content-type:application/json {"appId":"ak_demo_chat","messageId":"..."} \x00 ``` ### SEND 帧 — 同步离线消息 ``` SEND destination:/app/chat.sync content-type:application/json {"appId":"ak_demo_chat"} \x00 ``` ### MESSAGE 帧 — 接收消息 ``` MESSAGE destination:/user/queue/messages message-id:... {"id":"...","fromId":"user_002","toId":"user_001","chatType":"SINGLE","msgType":"TEXT","content":"Hello","status":"SENT","createdAt":1715000000000} \x00 ``` ### ERROR 帧 ``` ERROR message:Unauthorized Unauthorized \x00 ``` --- ## 订阅路径 | 路径 | 说明 | |------|------| | `/user/queue/messages` | 个人消息队列(登录后自动订阅)| | `/topic/group/{groupId}` | 群消息频道 | --- ## 服务端配置 基于 Spring WebSocket + STOMP: ```java @Configuration @EnableWebSocketMessageBroker public class WebSocketConfig implements WebSocketMessageBrokerConfigurer { @Override public void configureMessageBroker(MessageBrokerRegistry registry) { registry.enableSimpleBroker("/topic", "/queue"); registry.setApplicationDestinationPrefixes("/app"); registry.setUserDestinationPrefix("/user"); } @Override public void registerStompEndpoints(StompEndpointRegistry registry) { registry.addEndpoint("/ws/im") .setAllowedOriginPatterns("*") .withSockJS(); registry.addEndpoint("/ws/im") .setAllowedOriginPatterns("*"); } } ``` --- ## 自定义客户端接入 如果业务方不使用官方 SDK,可按以下流程自建客户端: 1. 通过 `wss://host/ws/im?token=xxx` 建立 WebSocket 2. 发送 STOMP CONNECT 帧(携带 `Authorization: Bearer {token}`) 3. 收到 CONNECTED 后,订阅 `/user/queue/messages` 4. 发送消息时构造 STOMP SEND 帧,`destination: /app/chat.send` 5. 收到服务端 MESSAGE 帧后解析 JSON body [→ Server API 文档 →](./api)