本项目有两个文档: websocket对接文档 和 HTTP协议的API文档
本文档为websocket对接文档
HTTP协议的API以Swagger实时生成为准
Swagge文档地址:
本地环境 api文档(实时更新 开发查看此文档): IP可能有变化 联系后端
http://192.168.1.89/api/doc.html#/home
账号密码admin admin
测试外网 api文档:
https://wstest.im199.com/api/doc.html#/home
只包含api接口文档 websocket对接说明在此文档中
web端. 安卓端. ios端. flutter等一切支持websocket的语言
即时通讯服务中的每一个终端称为一个「Client」。Client 拥有一个在应用内唯一标识自己的 ID(clientId)。这个 ID 由应用自己定义,必须是 由任意英文字母、数字、半角下划线与半角短横线组成,可以纯数字,不超过 64个字符的字符串组成。在大部分场合,Client 都可以对应到应用中的某个「用户」,但是并不是只有真的用户才能作为「Client」,你完全可以把一个探测器当成一个「Client」,把它收集到的数据通过即时通讯服务广播给更多「人」。
要使用即时通讯服务,每一个终端设备需要首先建立与即时通讯云服务端的 WebSocket 长连接,并使用唯一的 clientId 来加入即时通讯服务,我们把这一过程称为「登录」。请注意这里的登录仅仅指客户端登录即时通讯服务,与应用层面的用户账户注册登录是不一样的。
appKey为应用在蔚可云的唯一标识, appSecret为安全密钥, 均由蔚可云控制台或联系客服下发,给应用接入方安全验证密钥,生产环境appSecret不建议保存在接入方前端客户端, appKey与appSecret总是成对出现和使用
sign 由接入方后端生成, 进行加签的参数: MD5{timestamp + clientId + appKey + appSecret} timestamp:毫秒时间戳 clientId:由后端生成
在生产环境中,你需要自行部署服务器签发 sign
用户登录之后,与其他人(client)进行消息沟通,即为开启了一个「对话(Conversation)」。在即时通讯服务中,「对话」包含了沟通的用户群体(成员),也是所有消息依托的媒介:消息都是由某一个 Client 发往一个「对话」。终端用户在开始聊天之前,需要先创建或者加入一个对话,然后再邀请其他人进来(可选),之后所有参与者在这个对话内进行交流。
已接收为客户端接收到该消息,已经保存到本地缓存中,用户还未打开会话查看该条消息的情况. 服务器将不会再次下发已接收状态的离线消息,未接收的消息会在拉取离线消息时返回
已读为客户端已经查看该消息

本文展示如何在服务端部署一个 sign 生成器。
java示例代码 ,供客户应用后端参考
x
import org.springframework.util.DigestUtils;private void getSign(String timestamp, String clientId, String appKey, String appSecret) { String data = timestamp + clientId + appKey + appSecret; String sign = DigestUtils.md5DigestAsHex(data.getBytes());}
public static void main(String[] args) { String clientId = "client_123123"; String appKey = "elLwpel1gWCHDqZy"; String appSecret = "68809bb5a9077a83631aeb0b17b5965d6b2302faf2ab3737"; String timestamp = String.valueOf(new Date().getTime()); getSign(timestamp, clientId, appKey, appSecret);}第三方应用后端需要响应的参数:
x
{ "timestamp": "1628838135066", "clientId": "client_3334444", "appKey": "D13ug9jsWbJbeVx1", "sign": "c15a886fe4114dba2c8f078369e6bec9"}ws://localhost:8899/ws?token=xxxxxx&platform=1
示例:
ws://localhost:8899/ws?token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJhdWQiOiJ3ZWIiLCJjbGllbnRJZCI6ImhhaGFoXzMwIiwiaXNzIjoid2VjbG91ZF9pbSIsImFwcEtleSI6ImVsTHdwZWwxZ1dDSERxWnkiLCJleHAiOjE2MjkwOTY0MzksImlhdCI6MTYyMDQ1NjQzOSwianRpIjoiNDA1YzE3MWM2Njc5NGJmMDllNGRjZDdhNzA0ZjY3YTgifQ.7g2J_0q9UnuWszpuapSJUXJEwVevvI8Rm2Srg3594Lk&platform=1
| 字段名 | 字段类型 | 是否可空 | 说明 |
|---|---|---|---|
| token | String | 否 | token |
| platform | int | 是 | 设备平台类型: 1 安卓; 2 ios; 3 web |
本地环境
ws://192.168.1.89:8899/ws?token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJhdWQiOiJ3ZWIiLCJjbGllbnRJZCI6ImFhYWFhMyIsImlzcyI6IndlY2xvdWRfaW0iLCJhcHBLZXkiOiJRTnRQM0VqdEx3MjZla3QwIiwiZXhwIjoxNjc2NjYzNTkyLCJpYXQiOjE2MjY2ODQ1ODQsImp0aSI6ImY3NWVkODljMGZlZDQ0OWViZTczNzdiNmRlZTNhMDNlIn0.QxzGhpIpzYmJDaFGmdrMynWBkM7umtT5SnSSBKu46UY
测试外网
wss://wstest.im199.com/ws?token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJhdWQiOiJ3ZWIiLCJjbGllbnRJZCI6ImFiY2QxIiwiaXNzIjoid2VjbG91ZF9pbSIsImFwcEtleSI6IkpLdE5IZnJWVXdzaGF4ek4iLCJleHAiOjE2MjgzMjMxNDMsImlhdCI6MTYyMzEzOTE0MywianRpIjoiNWU3NzU5ZjM2ODQ3NDFiMzg4MGEyYjkwMjQ0OWZjZmYifQ.CC-iuGjNwQLH4VxFI2wZEPuP4AGabOUOiRh9snp3IB4
生产环境
wss://ws.im199.com/ws?token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJhdWQiOiJ3ZWIiLCJjbGllbnRJZCI6ImFiY2QxIiwiaXNzIjoid2VjbG91ZF9pbSIsImFwcEtleSI6IkpLdE5IZnJWVXdzaGF4ek4iLCJleHAiOjE2MjgzMjMxNDMsImlhdCI6MTYyMzEzOTE0MywianRpIjoiNWU3NzU5ZjM2ODQ3NDFiMzg4MGEyYjkwMjQ0OWZjZmYifQ.CC-iuGjNwQLH4VxFI2wZEPuP4AGabOUOiRh9snp3IB4
1:响应请求(用于im聊天)
2:下发在线用户消息
3:下发在线消息事件类型
4:下发单人在线RTC事件通知
5:响应请求(用于RTC音视频通话)
(xx表示为某客户端)
以上基础平台固定类型均使用负数,所有正数留给自定义扩展类型使用,0 作为「没有类型」被保留起来。
reqId 为每次客户端通过websocket通道发送请求的唯一request Id, 用来标识每次请求,方便定位问题,以及用于绑定服务端响应对此请求request id的数据.
websocket像服务端发送数据不同于http请求接口. http发送请求 会一个请求对应一个响应,客户端接收也知道该响应数据是针对哪个请求的.
websocket是异步的 有可能你很快速的发送了几条消息,服务器响应的数据不一定是按你发送的消息顺序响应, 所以你每个请求要自己定一个id, 服务器就算乱序响应数据,客户端也能知道响应的数据对应哪个请求
cmd 为请求指令
data 为数据,所有需要发送的数据都在此参数下
data内的参数: toConversation(会话id)与type(消息类型)为固定的,其它参数名与参数值皆可由使用方自定义
reqId 一个请求唯一的id,服务端响应时,会将对应的id与数据一同返回
cmd 为响应指令



示例一: 必传参数:
{"reqId":"123123123","cmd":1,"data":{ "toConversation":1402147846261706752, "type":-1, "text":"你好,这是一123个纯文本消息" }}示例二: 全部可选参数:
x
{"reqId":"123123123","cmd":1,"data":{ "push":{ "title":"收到一条新消息", "subTitle":"点击查看" }, "diyAbcd":"aaaa自已定义字段的值", "toConversation":1402147846261706752, "type":-1, "text":"你好,这是一123个纯文本消息", "attrs":{ "a":"用户自定义的一些键值对", "b":"用户自定义的一些键值对" } }}参数描述
| 字段名 | 字段类型 | 是否可空 | 说明 |
|---|---|---|---|
| cmd | String | 否 | 指令码 |
| data | Object | 否 | 除toConversation与type为固定的参数,其它参数皆可由使用方自定义 |
| attrs | Object | 是 | 自定义拓展字段 |
| toConversation | Long | 否 | 发送到会话id |
| diyParam自定义字段 | Object | 是 | 自定义拓展字段 |
| push | String | 否 | 客户端自定义系统推送内容 |
xxxxxxxxxx{ "cmd":2, "code":200, "msg":"成功", "data":{ "msgId":"1394207796915998720" }, "reqId":"123123123"}参数描述
| 字段名 | 字段类型 | 是否可空 | 说明 |
|---|---|---|---|
| cmd | String | 否 | 指令码 |
| msgId | String | 否 | 消息唯一ID |
xxxxxxxxxx{ "cmd":1, "code":200, "msg":"成功", "data":{ "msgId":"1394207796915998720", "createTime":1621240016587, "withdrawTime":null, "sender":"hahah_30", "content":{ "diyAbcd":"aaaa自已定义字段的值", "text":"你好,这是一123个纯文本消息", "type":-1, "attrs":{ "a":"用户自定义的一些键值对", "b":"用户自定义的一些键值对" } }, "withdraw":false, "event":false, "system":false, "at":null, "conversationId":"1394188055950266368" }, "reqId":null}参数描述
| 字段名 | 字段类型 | 是否可空 | 说明 |
|---|---|---|---|
| cmd | String | 否 | 指令码 |
| data | Object | 否 | 除toConversation与type为固定的参数,其它参数皆可由使用方自定义 |
| attrs | Object | 是 | 自定义拓展字段 |
| toConversation | Long | 否 | 发送到会话id |
| diyParam自定义字段 | Object | 是 | 自定义拓展字段 |
| push | String | 否 | 客户端自定义系统推送内容 |
| sender | String | 否 | 发送方 |
| withdrawTime | time | 是 | 撤回时间戳 |
| createTime | time | 否 | 消息发送时间戳 |
| at | String | 否 | 提到了其他客户端,以英文逗号分开 |
| withdraw | Boolean | 是 | 是否撤回 |
| event | Boolean | 是 | 是否为事件类型 |
| withdraw | Boolean | 是 | 是否撤回 |
| system | Boolean | 是 | 是否为系统消息 |
已接收回执需参考API对接文档
xxxxxxxxxx{"reqId":"123123123","cmd":1,"data":{ "toConversation":1394188055950266368, "type":-2, "file": { "url": "http://ac-p2bpmgci.clouddn.com/246b8acc-2e12-4a9d-a255-8d17a3059d25", // 必要参数 "objId": "54699d87e4b0a56c64f470a4", // 文件对应的AVFile.objectId "metaData": { "name": "IMG_20141223.jpeg", // 图像的名称 "format": "png", // 图像的格式 "height": 768, // 单位:像素 "width": 1024, // 单位:像素 "size": 18 // 单位:b } }, "attrs":{} }}上面是完整的例子,如果只想简单的发送图像 URL:
xxxxxxxxxx{"reqId":"123123123","cmd":1,"data":{ "toConversation":1394188055950266368, "type":-2, "file": { "url": "http://ac-p2bpmgci.clouddn.com/246b8acc-2e12-4a9d-a255-8d17a3059d25", // 必要参数 "objId": "54699d87e4b0a56c64f470a4", // 文件对应的AVFile.objectId "metaData": { "name": "IMG_20141223.jpeg", // 图像的名称 "format": "png", // 图像的格式 "height": 768, // 单位:像素 "width": 1024, // 单位:像素 "size": 18 // 单位:b } }}如视频 位置 音频 发送红包 好友验证等等
可参考:https://leancloud.cn/docs/realtime_v2.html#hash939050100
xxxxxxxxxx{"reqId":"123123123","cmd":1,"data":{ "toConversation":1394188055950266368, "type":由应用自定义, "应用自定义参数": 应用自定义值 }}
receiverId:接收方客户端id
conversationId:会话id
type为-1009 : 某消息已接收状态
msgId: 消息id;
该event事件消息类型不需要已读和已接收回执,不会保存进离线,仅下发给当前在线会话客户端.
xxxxxxxxxx{ "cmd":3, "code":200, "msg":"成功", "data":{ "msgId":1427109835333308416, "createTime":1629086007054, "withdrawTime":null, "sender":"aaaaa1", "content":{ "receiverId":"aaaaa1", "type":"-1009" }, "event":true, "conversationId":1427109730563788800 }, "reqId":null}参数描述
| 字段名 | 字段类型 | 是否可空 | 说明 |
|---|---|---|---|
| cmd | String | 否 | 指令码 |
| conversationId | Long | 否 | 会话id |
| sender | String | 否 | 发送方 |
| createTime | time | 否 | 消息发送时间戳 |
| event | Boolean | 是 | 是否为事件类型 |
receiverId:接收方客户端id
conversationId:会话id
type为-1010 : 某消息已读状态
msgId: 消息id;
该event事件消息类型不需要回执,不会保存进离线,仅下发给当前在线会话客户端.
xxxxxxxxxx{ "cmd":3, "code":200, "msg":"成功", "data":{ "msgId":1427109835333308416, "createTime":1629086007084, "sender":"aaaaa1", "content":{ "receiverId":"aaaaa1", "type":"-1010" }, "event":true, "conversationId":1427109730563788800 }, "reqId":null}参数描述
| 字段名 | 字段类型 | 是否可空 | 说明 |
|---|---|---|---|
| cmd | String | 否 | 指令码 |
| conversationId | Long | 否 | 会话id |
| sender | String | 否 | 发送方 |
| createTime | time | 否 | 消息发送时间戳 |
| event | Boolean | 是 | 是否为事件类型 |