Commit c2933f38 by giaogiao

添加md文档

parent d9f5e117
# wecloud-im 前端Websocket对接文档
# wecloud-im 前端Websocket对接文档
## 文档描述
此文档为websocket技术对接文档
## 适用对象
web端. 安卓端. ios端. flutter等一切支持websocket的语言
### 本地API文档地址
http://192.168.1.110:8082/api/doc.html#/home
账号密码admin admin
以上只包含api接口文档 websocket对接说明在此文档中
### 测试外网
api文档:
```
https://wstest.im199.com/api/doc.html#/home
```
___
测试外网api请求示例:
```
https://wstest.im199.com/api/imApplication/add
```
___
websocket连接示例
```
wss://wstest.im199.com/ws?token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJhdWQiOiJ3ZWIiLCJjbGllbnRJZCI6ImFiY2QxIiwiaXNzIjoid2VjbG91ZF9pbSIsImFwcEtleSI6IkpLdE5IZnJWVXdzaGF4ek4iLCJleHAiOjE2MjgzMjMxNDMsImlhdCI6MTYyMzEzOTE0MywianRpIjoiNWU3NzU5ZjM2ODQ3NDFiMzg4MGEyYjkwMjQ0OWZjZmYifQ.CC-iuGjNwQLH4VxFI2wZEPuP4AGabOUOiRh9snp3IB4
```
_______
### 生产环境
ws.im199.com
api文档:
```
https://ws.im199.com/api/doc.html#/home
```
___
测试外网api请求示例:
```
https://ws.im199.com/api/imApplication/add
```
___
websocket连接示例
```
wss://ws.im199.com/ws?token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJhdWQiOiJ3ZWIiLCJjbGllbnRJZCI6ImFiY2QxIiwiaXNzIjoid2VjbG91ZF9pbSIsImFwcEtleSI6IkpLdE5IZnJWVXdzaGF4ek4iLCJleHAiOjE2MjgzMjMxNDMsImlhdCI6MTYyMzEzOTE0MywianRpIjoiNWU3NzU5ZjM2ODQ3NDFiMzg4MGEyYjkwMjQ0OWZjZmYifQ.CC-iuGjNwQLH4VxFI2wZEPuP4AGabOUOiRh9snp3IB4
```
_______
## 核心概念说明
### clientId、用户和登录
即时通讯服务中的每一个终端称为一个「Client」。Client 拥有一个在应用内唯一标识自己的 ID(`clientId`)。这个 ID 由应用自己定义,必须是 **由任意英文字母、数字、半角下划线与半角短横线组成,可以纯数字,不超过 64个字符的字符串组成**。在大部分场合,Client 都可以对应到应用中的某个「用户」,但是并不是只有真的用户才能作为「Client」,你完全可以把一个探测器当成一个「Client」,把它收集到的数据通过即时通讯服务广播给更多「人」。
要使用即时通讯服务,每一个终端设备需要首先建立与即时通讯云端的 WebSocket 长连接,并使用唯一的 `clientId` 来加入即时通讯服务,我们把这一过程称为「登录」。请注意这里的登录仅仅指客户端登录即时通讯服务,与应用层面的用户账户注册登录是不一样的。
### appKey与appSecret
为im云下发给接入方安全保护密钥,不建议保存在接入方前端客户端, appKey与appSecret总是成对出现和使用
### sign签名
sign 由接入方后端生成, 进行加签的参数: MD5{timestamp + clientId + appKey + appSecret}
timestamp:毫秒时间戳
clientId:由后端生成
**在生产环境中,你需要自行部署服务器签发 sign**
### 对话(Conversation)
用户登录之后,与其他人(client)进行消息沟通,即为开启了一个「对话(Conversation)」。在即时通讯服务中,「对话」包含了沟通的用户群体(成员),也是所有消息依托的媒介:消息都是由某一个 Client 发往一个「对话」。终端用户在开始聊天之前,需要先创建或者加入一个对话,然后再邀请其他人进来(可选),之后所有参与者在这个对话内进行交流。
### 已读/已接收
**已接收**为客户端接收到该消息,已经保存到本地缓存中,用户还未打开会话查看该条消息的情况. 服务器将不会再次下发已接收状态的离线消息,未接收的消息会在拉取离线消息时返回
**已读**为客户端已经查看该消息
## 客户端登陆
![wc_im_client连接流程-Page-1](https://tva1.sinaimg.cn/large/008i3skNgy1guv1su6a35j60d80gzaan02.jpg)
1. appKey, appSecret为im云下发给客户方安全保护密钥,不建议保存在前端客户端;
2. 第三方应用服务端需提供获取sign的接口, sign 由MD5{timestamp + clientId + appKey + appSecret},其中clientId由后端生成;
3. 前端拿到sign后,调用验证sign接口进行获取token;
4. websocket连接初始化需要带上token即可连接成功;
### 第三方应用后端生成sign接口示例
**java**示例代码 ,供客户应用后端参考
```java
private void getSign(String timestemp, String clientId, String appKey, String appSecret) {
String sign = new MD5().digestHex(timestemp + clientId + appKey + appSecret);
}
public static void main(String[] args) {
String clientId = "client_123123";
String appKey = "elLwpel1gWCHDqZy";
String appSecret = "68809bb5a9077a83631aeb0b17b5965d6b2302faf2ab3737";
String timestemp = String.valueOf(new Date().getTime());
getSign(timestemp, clientId, appKey, appSecret);
}
```
后端必须需要响应参数:
```
{
"timestamp": "1628838135066",
"clientId": "client_3334444",
"appKey": "D13ug9jsWbJbeVx1",
"sign": "c15a886fe4114dba2c8f078369e6bec9"
}
```
### 连接WebSocket
ws://localhost:8899/ws?token=xxxxxx
示例:
```
ws://localhost:8899/ws?token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJhdWQiOiJ3ZWIiLCJjbGllbnRJZCI6ImhhaGFoXzMwIiwiaXNzIjoid2VjbG91ZF9pbSIsImFwcEtleSI6ImVsTHdwZWwxZ1dDSERxWnkiLCJleHAiOjE2MjkwOTY0MzksImlhdCI6MTYyMDQ1NjQzOSwianRpIjoiNDA1YzE3MWM2Njc5NGJmMDllNGRjZDdhNzA0ZjY3YTgifQ.7g2J_0q9UnuWszpuapSJUXJEwVevvI8Rm2Srg3594Lk
```
## 请求CMD指令说明
- 1: 发送消息
- 3: 单人WebRTC
## 响应CMD指令说明
- 1:响应用户请求
- 2:下发在线用户消息
- 3:下发在线消息事件类型
- 4:下发单人在线RTC事件
- 401:无权限 token失效
## 消息type说明
- 文本消息 -1
- 图像消息 -2
- 音频消息 -3
- 视频消息 -4
- 位置消息 -5
- 文件消息 -6
## 事件类型type
(xx表示为某客户端)
- xx邀请xx加入会话 -1007
- xx被xx移出会话 -1008
- xx已接收某消息 -1009
- xx已读某条消息 -1010
- 你被xx拉入新会话 -1011
以上基础平台固定类型均使用负数,所有正数留给自定义扩展类型使用,0 作为「没有类型」被保留起来。
## code错误码
- 401 用户token无效
## websocket客户端请求参数说明
**reqId** 为每次客户端通过websocket通道发送请求的唯一request Id, 用来标识每次请求,方便定位问题,以及用于绑定服务端响应对此请求request id的数据.
websocket像服务端发送数据不同于http请求接口.
http发送请求 会一个请求对应一个响应,客户端接收也知道该响应数据是针对哪个请求的.
websocket是异步的 有可能你很快速的发送了几条消息,服务器响应的数据不一定是按你发送的消息顺序响应, 所以你每个请求要自己定一个id, 服务器就算乱序响应数据,客户端也能知道响应的数据对应哪个请求
**cmd** 为请求指令
**data** 为数据,所有需要发送的数据都在此参数下
**data内**的参数: **toConversation**(会话id)与**type**(消息类型)为固定的,其它参数名与参数值皆可由使用方自定义
## websocket服务器响应参数说明
**reqId** 一个请求唯一的id,服务端响应时,会将对应的id与数据一同返回
**cmd** 为响应指令
![image-20210521104503728](https://tva1.sinaimg.cn/large/008i3skNly1gqpurt4tgnj30py0dc3zd.jpg)
## 消息收发流程
![IM_client在线消息发送流程](https://tva1.sinaimg.cn/large/008i3skNgy1guv1rkeif7j60ix0hlgmc02.jpg)
![IM_client在线消息接收流程](https://tva1.sinaimg.cn/large/008i3skNgy1guv1rdrnq3j60fw0dg3yx02.jpg)
### 1. 客户端发送文本消息
```json
{
"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 | 否 | 客户端自定义系统推送内容 |
### 2. 服务端响应给发送者
```json
{
"cmd":2,
"code":200,
"msg":"成功",
"data":{
"msgId":"1394207796915998720"
},
"reqId":"123123123"
}
```
**参数描述**
| 字段名 | 字段类型 | 是否可空 | 说明 |
| ------------------ | -------- | -------- | -------------- |
| cmd | String | 否 | 指令码 |
| msgId | String | 否 | 消息唯一ID |
### 3. 接收方收到在线消息
```json
{
"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 | 是 | 是否为系统消息 |
### 4.接收方收到,需要回执
已接收回执需参考API对接文档
## 发送图片
```json
{
"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:
```json
{
"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
```json
{
"reqId":"123123123",
"cmd":1,
"data":{
"toConversation":1394188055950266368,
"type":由应用自定义,
"应用自定义参数": 应用自定义值
}
}
```
## 客户端在线接收事件类型消息
### 事件类型type (xx表示为某客户端)
- xx邀请xx加入会话 -1007
- xx被xx移出会话 -1008
- xx已接收某消息 -1009
- xx已读某条消息 -1010
- 你被xx拉入新会话 -1011
### 服务端在线下发 某消息*已接收*状态
receiverId:接收方客户端id
conversationId:会话id
type为-1009 : 某消息已接收状态
msgId: 消息id;
该event事件消息类型不需要已读和已接收回执,不会保存进离线,仅下发给当前在线会话客户端.
```json
{
"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事件消息类型不需要回执,不会保存进离线,仅下发给当前在线会话客户端.
```json
{
"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 | 是 | 是否为事件类型 |
# wecloud-RTC音视频客户端对接文档
# wecloud-RTC音视频客户端对接文档
## 文档描述
此文档为单人RTC音视频通讯技术对接文档
由于RTC基于wecloud-im即时通讯服务,**对接RTC前,需要先对接wecloud-im服务**
## 流程图
![单人WebRTC发起流程图](https://tva1.sinaimg.cn/large/008i3skNgy1guxhnn6x64j60jr0xgmz302.jpg)
# 指令说明
subType子类型:
创建会话:create
接收到RTC:rtcCall
## 发起RTC音视频通话
client发送方向服务端发送数据:
```json
{
"reqId":"555111",
"cmd":3,
"data":{
"diyParam自定义字段":"aaaa自已定义字段的值",
"toConversation":null,
"toClient":"client_3030",
"subType":"create",
"push":{
"title":"xxx正在邀请你视频通话",
"subTitle":"点击接听"
},
"attrs":{
"a":"示例: 用户自定义的一些键值对",
"b":"示例: 存储用户自定义的一些键值对"
}
}
}
```
**说明:** toConversation会话ID可以为空, 为空时通话记录将不会记录到会话当中, 如"未接听", "已拒绝"等事件通知不会写入到会话的聊天记录中.
**参数描述**
| 字段名 | 字段类型 | 是否可空 | 说明 |
| ---- | -------- | -- | ------ |
| cmd | String | 否 | 指令码 |
| attrs | Object | 是 | 自定义拓展字段 |
| toConversation | Long | 是 | 会话id,可为空 |
| diyParam自定义字段 | Object | 是 | 自定义拓展字段 |
| push | String | 是 | 接收方展示的推送内容 |
| subType | String | 否 | 子类型 |
| toClient | String | 否 | 被邀请的客户端ID |
## 接收方收到RTC音视频通话邀请
服务端向client接收方下发数据:
```json
{
"reqId":"",
"cmd":4,
"data":{
"diyParam自定义字段":"aaaa自已定义字段的值",
"toConversation":null,
"subType":"rtcCall",
"sender":"client_1010",
"attrs":{
"a":"示例: 用户自定义的一些键值对",
"b":"存储用户自定义的一些键值对"
}
}
}
```
**参数描述**
| 字段名 | 字段类型 | 是否可空 | 说明 |
| ---- | -------- | -- | ------ |
| cmd | String | 否 | 指令码 |
| attrs | Object | 是 | 自定义拓展字段 |
| toConversation | Long | 否 | 会话id |
| diyParam自定义字段 | Object | 是 | 自定义拓展字段 |
| subType | String | 否 | 子类型 |
| sender | String | 否 | 发起通话的客户端ID |
## 接收方同意加入房间
client接收方向服务端发送数据:
```json
{
"reqId":"123",
"cmd":3,
"data":{
"diyParam自定义字段":"aaaa自已定义字段的值",
"toConversation":1402147846261706752,
"subType":"agree",
"attrs":{}We
}
}
```
**参数描述**
| 字段名 | 字段类型 | 是否可空 | 说明 |
| ---- | -------- | -- | ------ |
| cmd | String | 否 | 指令码 |
| attrs | Object | 是 | 自定义拓展字段 |
| toConversation | Long | 否 | 会话id |
| diyParam自定义字段 | Object | 是 | 自定义拓展字段 |
| subType | String | 否 | 子类型 |
### 通知发送方: 接收方同意加入房间
服务端向发送方下发数据:
```json
{
"reqId":"123",
"cmd":4,
"data":{
"diyParam自定义字段":"aaaa自已定义字段的值",
"toConversation":1402147846261706752,
"subType":"agree"
}
}
```
## 接收方拒绝加入房间
client接收方向服务端发送数据:
```json
{
"reqId":"123",
"cmd":3,
"data":{
"diyParam自定义字段":"aaaa自已定义字段的值",
"toConversation":1402147846261706752,
"subType":"reject",
"attrs":{}
}
}
```
**说明:**
**参数描述**
| 字段名 | 字段类型 | 是否可空 | 说明 |
| ---- | -------- | -- | ------ |
| cmd | String | 否 | 指令码 |
| attrs | Object | 是 | 自定义拓展字段 |
| toConversation | Long | 否 | 会话id |
| diyParam自定义字段 | Object | 是 | 自定义拓展字段 |
| subType | String | 否 | 子类型 |
### 通知发送方: 接收方拒绝加入房间
服务端向发送方下发数据:
```json
{
"reqId":"123",
"cmd":4,
"data":{
"diyParam自定义字段":"aaaa自已定义字段的值",
"toConversation":1402147846261706752,
"subType":"reject"
}
}
```
## 流媒体描述信息SDP转发
(服务端仅负责转发)(ice_candidate,anser,offer)
## 视频切音频
## 离开房间
## 系统电话繁忙
## 断线重连
## 发送心跳
## 对方是否还挂起
## 挂断
## 确认离开
## 确认是否离开
## 查询对方是否离开
# wecloud-im 客户端对接文档
# wecloud-im 客户端对接文档
[TOC]
## 生产环境
ws.im199.com
websocket连接示例
```
wss://ws.im199.com/ws?token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJhdWQiOiJ3ZWIiLCJjbGllbnRJZCI6ImFiY2QxIiwiaXNzIjoid2VjbG91ZF9pbSIsImFwcEtleSI6IkpLdE5IZnJWVXdzaGF4ek4iLCJleHAiOjE2MjgzMjMxNDMsImlhdCI6MTYyMzEzOTE0MywianRpIjoiNWU3NzU5ZjM2ODQ3NDFiMzg4MGEyYjkwMjQ0OWZjZmYifQ.CC-iuGjNwQLH4VxFI2wZEPuP4AGabOUOiRh9snp3IB4
```
_______
## 核心概念说明
### clientId、用户和登录
即时通讯服务中的每一个终端称为一个「Client」。Client 拥有一个在应用内唯一标识自己的 ID(`clientId`)。这个 ID 由应用自己定义,必须是 **由任意英文字母、数字、半角下划线与半角短横线组成,可以纯数字,不超过 64个字符的字符串组成**。在大部分场合,Client 都可以对应到应用中的某个「用户」,但是并不是只有真的用户才能作为「Client」,你完全可以把一个探测器当成一个「Client」,把它收集到的数据通过即时通讯服务广播给更多「人」。
要使用即时通讯服务,每一个终端设备需要首先建立与即时通讯云端的 WebSocket 长连接,并使用唯一的 `clientId` 来加入即时通讯服务,我们把这一过程称为「登录」。请注意这里的登录仅仅指客户端登录即时通讯服务,与应用层面的用户账户注册登录是不一样的。
### 对话(Conversation)
用户登录之后,与其他人进行消息沟通,即为开启了一个「对话(Conversation)」。在即时通讯服务中,「对话」包含了沟通的用户群体(成员),也是所有消息依托的媒介:消息都是由某一个 Client 发往一个「对话」。终端用户在开始聊天之前,需要先创建或者加入一个对话,然后再邀请其他人进来(可选),之后所有参与者在这个对话内进行交流。
### 已读/已接收
**已接收**为客户端接收到该消息,已经保存到本地缓存中,用户还未打开会话查看该条消息的情况. 服务器将不会再次下发已接收状态的离线消息,未接收的消息会在拉取离线消息时返回
**已读**为客户端已经查看该消息
## 客户端登陆api
<img src="https://tva1.sinaimg.cn/large/008i3skNly1gqlielspokj30s80xe0vv.jpg" alt="image-20210517140904878" style="zoom:67%;" />
1. appKey, appSecret为im云下发给客户方安全保护密钥,不建议保存在前端客户端,
2. 客户前端需提供获取sign的接口, sign 由MD5{timestamp + clientId + appKey + appSecret},其中clientId由后端生成
3. 前端拿到sign后,调用验证sign接口进行获取token
4. websocket连接初始化需要带上token即可连接成功
### 生成sign示例
java示例代码 ,供客户应用后端参考
```java
private void getSign(String timestemp, String clientId, String appKey, String appSecret) {
String sign = new MD5().digestHex(timestemp + clientId + appKey + appSecret);
}
public static void main(String[] args) {
String clientId = "client_123123";
String appKey = "elLwpel1gWCHDqZy";
String appSecret = "68809bb5a9077a83631aeb0b17b5965d6b2302faf2ab3737";
String timestemp = String.valueOf(new Date().getTime());
getSign(timestemp, clientId, appKey, appSecret);
}
```
后端需要响应参数示例:
```
{
"timestamp": "1628838135066",
"clientId": "client_3334444",
"appKey": "D13ug9jsWbJbeVx1",
"sign": "c15a886fe4114dba2c8f078369e6bec9"
}
```
### sign
### 连接websocket
ws://localhost:8899/ws?token=xxxxxx
示例:
```
ws://localhost:8899/ws?token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJhdWQiOiJ3ZWIiLCJjbGllbnRJZCI6ImhhaGFoXzMwIiwiaXNzIjoid2VjbG91ZF9pbSIsImFwcEtleSI6ImVsTHdwZWwxZ1dDSERxWnkiLCJleHAiOjE2MjkwOTY0MzksImlhdCI6MTYyMDQ1NjQzOSwianRpIjoiNDA1YzE3MWM2Njc5NGJmMDllNGRjZDdhNzA0ZjY3YTgifQ.7g2J_0q9UnuWszpuapSJUXJEwVevvI8Rm2Srg3594Lk
```
## 请求CMD指令说明
- 1: 发送消息
- 2: RTC
## 响应CMD指令说明
1响应用户请求
2下发在线用户消息
3下发在线事件类型消息
401:无权限 token失效
## 消息type说明
- 文本消息 -1
- 图像消息 -2
- 音频消息 -3
- 视频消息 -4
- 位置消息 -5
- 文件消息 -6
- ### 事件类型type (xx表示为某客户端)
- xx邀请xx加入会话 -1007
- xx被xx移出会话 -1008
- xx已接收某消息 -1009
- xx已读某条消息 -1010
- 你被xx拉入新会话 -1011
以上类型均使用负数,所有正数留给自定义扩展类型使用,0 作为「没有类型」被保留起来。
## code错误码
- 401 用户token无效
## websocket客户端请求参数说明
**reqId** 为每次客户端通过websocket通道发送请求的唯一request Id, 用来标识每次请求,方便定位问题,以及用于绑定服务端响应对此请求request id的数据.
websocket像服务端发送数据不同于http请求接口.
http发送请求 会一个请求对应一个响应,客户端接收也知道该响应数据是针对哪个请求的.
websocket是异步的 有可能你很快速的发送了几条消息,服务器响应的数据不一定是按你发送的消息顺序响应, 所以你每个请求要自己定一个id, 服务器就算乱序响应数据,客户端也能知道响应的数据对应哪个请求
**cmd** 为请求指令
**data** 为数据,所有需要发送的数据都在此参数下
**data内**的参数: **toConversation**(会话id)与**type**(消息类型)为固定的,其它参数名与参数值皆可由使用方自定义
## websocket服务器响应参数说明
**reqId** 一个请求唯一的id,服务端响应时,会将对应的id与数据一同返回
**cmd** 为响应指令
![image-20210521104503728](https://tva1.sinaimg.cn/large/008i3skNly1gqpurt4tgnj30py0dc3zd.jpg)
## 消息收发流程
### 1. 客户端发送文本消息
```json
{
"reqId":"123123123",
"cmd":1,
"data":{
"push":{
"title":"收到一条新消息",
"subTitle":"发给12312123213这是一123个纯文本消息,发给12312123213这是一123个纯文本消息发给12312123213这是一123个纯文本消息"
},
"diyAbcd":"aaaa自已定义字段的值",
"toConversation":1402147846261706752,
"type":-1,
"text":"发给12312123213这是一123个纯文本消息,发给12312123213这是一123个纯文本消息发给12312123213这是一123个纯文本消息",
"attrs":{
"a":"attrs 阿道夫123123是用来213存储用户自定义的一些键值对,ttrs 阿道夫123123是用来213存储用户自定义的一些键值对",
"b":"attrs 阿道夫123123是用来213存储用户自定义的一些键值对,ttrs 阿道夫123123是用来213存储用户自定义的一些键值对"
}
}
}
```
data里面的参数 除toConversation与type为固定的,其它参数皆可由使用方自定义
push为客户端自定义系统推送内容
### 2. 发送成功服务端响应给发送者
```json
{
"cmd":2,
"code":200,
"msg":"成功",
"data":{
"msgId":"1394207796915998720"
},
"reqId":"123123123"
}
```
### 3. 接收方收到在线消息
```json
{
"cmd":1,
"code":200,
"msg":"成功",
"data":{
"msgId":"1394207796915998720",
"createTime":1621240016587,
"withdrawTime":null,
"sender":"hahah_30",
"content":{
"text":"发给12312123213这是一123个纯文本消息,发给12312123213这是一123个纯文本消息发给12312123213这是一123个纯文本消息",
"type":-1,
"attrs":{
"a":"attrs 阿道夫123123是用来213存储用户自定义的一些键值对,ttrs 阿道夫123123是用来213存储用户自定义的一些键值对",
"b":"attrs 阿道夫123123是用来213存储用户自定义的一些键值对,ttrs 阿道夫123123是用来213存储用户自定义的一些键值对"
}
},
"withdraw":false,
"event":false,
"system":false,
"at":null,
"conversationId":"1394188055950266368"
},
"reqId":null
}
```
### 4.接收方收到,需要回执
已接收回执需参考API对接文档
## 发送图片
```json
{
"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":{
"a":"attrs 存储用户自定义的一些键值对,ttrs 阿道夫123123是用来213存储用户自定义的一些键值对",
"b":"attrs 阿道夫123123是用来213存储用户自定义的一些键值对,ttrs 阿道夫123123是用来213存储用户自定义的一些键值对"
}
}
}
```
上面是完整的例子,如果只想简单的发送图像 URL:
```json
{
"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
```json
{
"reqId":"123123123",
"cmd":1,
"data":{
"toConversation":1394188055950266368,
"type":由应用自定义,
"应用自定义参数": 应用自定义值
}
}
```
## 客户端在线接收事件类型消息
### 事件类型type (xx表示为某客户端)
- xx邀请xx加入会话 -1007
- xx被xx移出会话 -1008
- xx已接收某消息 -1009
- xx已读某条消息 -1010
- 你被xx拉入新会话 -1011
### 服务端在线下发 某消息*已接收*状态
receiverId:接收方客户端id
conversationId:会话id
type为-1009 : 某消息已接收状态
msgId: 消息id;
该event事件消息类型不需要回执,不会保存进离线,仅下发给当前在线会话客户端.
```json
{
"cmd":3,
"code":200,
"msg":"成功",
"data":{
"msgId":1427109835333308416,
"createTime":1629086007054,
"withdrawTime":null,
"sender":"aaaaa1",
"content":{
"receiverId":"aaaaa1",
"type":"-1009"
},
"withdraw":false,
"event":true,
"system":false,
"at":null,
"conversationId":1427109730563788800
},
"reqId":null
}
```
### 服务端在线下发 某消息*已读*状态
receiverId:接收方客户端id
conversationId:会话id
type为-1010 : 某消息已读状态
msgId: 消息id;
该event事件消息类型不需要回执,不会保存进离线,仅下发给当前在线会话客户端.
```json
{
"cmd":3,
"code":200,
"msg":"成功",
"data":{
"msgId":1427109835333308416,
"createTime":1629086007084,
"withdrawTime":null,
"sender":"aaaaa1",
"content":{
"receiverId":"aaaaa1",
"type":"-1010"
},
"withdraw":false,
"event":true,
"system":false,
"at":null,
"conversationId":1427109730563788800
},
"reqId":null
}
```
# API 文档
**简介**:wecloud_im API Documents
**HOST**:https://ws.im199.com/
[TOC]
# token相关
## 验证sign,并返回token
**接口地址**:`/api/token/verify`
**请求方式**:`POST`
**请求数据类型**:`application/json`
**响应数据类型**:`*/*`
**接口描述**:根据客户方生成签名字符串 验证通过则下发token
**请求示例**:
```javascript
{
"timestamp": "",
"clientId": "",
"appKey": "",
"sign": ""
}
```
**请求参数**:
| 参数名称 | 参数说明 | in | 是否必须 | 数据类型 | schema |
| --------------------- | -------------------- | ------ | -------- | ------------- | ------------- |
| imTokenVerify | imTokenVerify | body | true | ImTokenVerify | ImTokenVerify |
| &emsp;&emsp;timestamp | 时间戳 | | false | string | |
| &emsp;&emsp;clientId | client客户端id | | false | string | |
| &emsp;&emsp;appKey | appkey | | false | string | |
| &emsp;&emsp;sign | 签名sign | | false | string | |
| token | Token Request Header | header | false | string | |
**响应状态**:
| 状态码 | 说明 | schema |
| ------ | ------------ | ------------------ |
| 200 | OK | ApiResult«TokenVo» |
| 201 | Created | |
| 401 | Unauthorized | |
| 403 | Forbidden | |
| 404 | Not Found | |
**响应参数**:
| 参数名称 | 参数说明 | 类型 | schema |
| ---------------------- | -------------------------------------- | -------------- | -------------- |
| code | | integer(int32) | integer(int32) |
| message | | string | |
| data | | TokenVo | TokenVo |
| &emsp;&emsp;token | | string | |
| &emsp;&emsp;id | 客户端id | integer(int64) | |
| &emsp;&emsp;attributes | 可选 自定义属性,供开发者扩展使用。 | string | |
**响应示例**:
```javascript
{
"code": 0,
"message": "",
"data": {
"token": "",
"id": 0,
"attributes": ""
}
}
```
# 会话表
## 创建会话
**接口地址**:`/api/conversation/create`
**请求方式**:`POST`
**请求数据类型**:`application/json`
**响应数据类型**:`*/*`
**接口描述**:后台可配置:两个客户端如果已经创建过会话,是否重复创建会话
**请求示例**:
```javascript
{
"name": "",
"attributes": {},
"clientIds": []
}
```
**请求参数**:
| 参数名称 | 参数说明 | in | 是否必须 | 数据类型 | schema |
| ---------------------- | --------------------------------------------------------- | ------ | -------- | -------------------- | -------------------- |
| imConversationCreate | imConversationCreate | body | true | ImConversationCreate | ImConversationCreate |
| &emsp;&emsp;name | 可选 对话的名字,可为群组命名。 | | false | string | |
| &emsp;&emsp;attributes | json格式,可选 自定义属性,供开发者扩展使用。 | | false | object | |
| &emsp;&emsp;clientIds | 可选 邀请加入会话的客户端,如创建单聊,则填入对方的clientId | | false | array | string |
| token | Token Request Header | header | false | string | |
**响应状态**:
| 状态码 | 说明 | schema |
| ------ | ------------ | --------------------------------- |
| 200 | OK | ApiResult«ImConversationCreateVo» |
| 201 | Created | |
| 401 | Unauthorized | |
| 403 | Forbidden | |
| 404 | Not Found | |
**响应参数**:
| 参数名称 | 参数说明 | 类型 | schema |
| -------------- | -------- | ---------------------- | ---------------------- |
| code | | integer(int32) | integer(int32) |
| message | | string | |
| data | | ImConversationCreateVo | ImConversationCreateVo |
| &emsp;&emsp;id | 会话id | integer(int64) | |
**响应示例**:
```javascript
{
"code": 0,
"message": "",
"data": {
"id": 0
}
}
```
## 批量修改单向隐藏或显示会话
**接口地址**:`/api/conversation/displayUpdate`
**请求方式**:`POST`
**请求数据类型**:`application/json`
**响应数据类型**:`*/*`
**接口描述**:拉取会话列表不展示已隐藏状态的会话,云端聊天记录不删除;假设有A和B两个用户,A删会话,B还能发; 如果B发了消息,A这边要重新把会话显示出来,并能显示之前的聊天记录
**请求示例**:
```javascript
{
"conversationIds": [],
"displayStatus": 0
}
```
**请求参数**:
| 参数名称 | 参数说明 | in | 是否必须 | 数据类型 | schema |
| --------------------------- | --------------------------- | ------ | -------- | -------------------- | -------------------- |
| imConversationDisplayUpdate | imConversationDisplayUpdate | body | true | 修改是否单向隐藏会话 | 修改是否单向隐藏会话 |
| &emsp;&emsp;conversationIds | 会话id | | false | array | integer |
| &emsp;&emsp;displayStatus | 显示状态 1显示 0不显示 | | false | integer(int32) | |
| token | Token Request Header | header | false | string | |
**响应状态**:
| 状态码 | 说明 | schema |
| ------ | ------------ | ------------------ |
| 200 | OK | ApiResult«boolean» |
| 201 | Created | |
| 401 | Unauthorized | |
| 403 | Forbidden | |
| 404 | Not Found | |
**响应参数**:
| 参数名称 | 参数说明 | 类型 | schema |
| -------- | -------- | -------------- | -------------- |
| code | | integer(int32) | integer(int32) |
| message | | string | |
| data | | boolean | |
**响应示例**:
```javascript
{
"code": 0,
"message": "",
"data": true
}
```
## 查询加入的会话列表
**接口地址**:`/api/conversation/getList`
**请求方式**:`POST`
**请求数据类型**:`application/json`
**响应数据类型**:`*/*`
**接口描述**:查询用户加入的非隐藏状态的会话列表 与每个会话的未读条数 成员
**请求参数**:
| 参数名称 | 参数说明 | in | 是否必须 | 数据类型 | schema |
| -------- | -------------------- | ------ | -------- | -------- | ------ |
| token | Token Request Header | header | false | string | |
**响应状态**:
| 状态码 | 说明 | schema |
| ------ | ------------ | ------------------------------------- |
| 200 | OK | ApiResult«List«MyConversationListVo»» |
| 201 | Created | |
| 401 | Unauthorized | |
| 403 | Forbidden | |
| 404 | Not Found | |
**响应参数**:
| 参数名称 | 参数说明 | 类型 | schema |
| ---------------------------------------- | -------------------------------------------------- | ----------------- | -------------------- |
| code | | integer(int32) | integer(int32) |
| message | | string | |
| data | | array | MyConversationListVo |
| &emsp;&emsp;id | 会话id | integer(int64) | |
| &emsp;&emsp;createTime | 创建时间 | string(date-time) | |
| &emsp;&emsp;creator | 创建者客户端id | string | |
| &emsp;&emsp;name | 可选 对话的名字,可为群组命名。 | string | |
| &emsp;&emsp;attributes | 可选 自定义属性,供开发者扩展使用。 | object | |
| &emsp;&emsp;system | 可选 对话类型标志,是否是系统对话,后面会说明。 | boolean | |
| &emsp;&emsp;msgNotReadCount | 未读消息条数 | integer(int64) | |
| &emsp;&emsp;members | 成员 | string | |
| &emsp;&emsp;lastMsg | 会话最后一条消息 | OfflineMsgDto | OfflineMsgDto |
| &emsp;&emsp;&emsp;&emsp;msgId | 消息id | | false |
| &emsp;&emsp;&emsp;&emsp;createTime | 创建时间 | | false |
| &emsp;&emsp;&emsp;&emsp;withdrawTime | 撤回时间 | | false |
| &emsp;&emsp;&emsp;&emsp;sender | 发送者客户端id | | false |
| &emsp;&emsp;&emsp;&emsp;content | 内容 | | false |
| &emsp;&emsp;&emsp;&emsp;withdraw | 0未撤回; 1已撤回 | | false |
| &emsp;&emsp;&emsp;&emsp;event | 0非事件; 1为事件 | | false |
| &emsp;&emsp;&emsp;&emsp;system | 0非系统通知; 1为系统通知 | | false |
| &emsp;&emsp;&emsp;&emsp;at | at他人,传入客户端id数组 | | false |
| &emsp;&emsp;&emsp;&emsp;notReadCount | 未读人数统计,全部人已读为0 | | false |
| &emsp;&emsp;&emsp;&emsp;notReceiverCount | 未接收人数统计,全部人已接收为0 | | false |
**响应示例**:
```javascript
{
"code": 0,
"message": "",
"data": [
{
"id": 0,
"createTime": "",
"creator": "",
"name": "",
"attributes": {},
"system": true,
"msgNotReadCount": 0,
"members": "",
"lastMsg": {
"msgId": 0,
"createTime": "",
"withdrawTime": "",
"sender": "",
"content": "",
"withdraw": true,
"event": true,
"system": true,
"at": "",
"notReadCount": 0,
"notReceiverCount": 0
}
}
]
}
```
# 消息存储表
## 查询某个会话历史消息分页列表
**接口地址**:`/api/imMessage/getHistoryMsg`
**请求方式**:`POST`
**请求数据类型**:`application/json`
**响应数据类型**:`*/*`
**接口描述**:
**请求示例**:
```javascript
{
"conversationId": 0,
"pageIndex": 1,
"pageSorts": [
{
"column": "",
"asc": true
}
],
"pageSize": 10,
"keyword": ""
}
```
**请求参数**:
| 参数名称 | 参数说明 | in | 是否必须 | 数据类型 | schema |
| ------------------------------ | ------------------------- | ------ | -------- | ------------------------- | ------------------------- |
| imHistoryMessagePageParam | imHistoryMessagePageParam | body | true | ImHistoryMessagePageParam | ImHistoryMessagePageParam |
| &emsp;&emsp;conversationId | 会话id | | false | integer(int64) | |
| &emsp;&emsp;pageIndex | 页码,默认为1 | | false | integer(int64) | |
| &emsp;&emsp;pageSorts | 排序 | | false | array | OrderItem |
| &emsp;&emsp;&emsp;&emsp;column | | | false | string | |
| &emsp;&emsp;&emsp;&emsp;asc | | | false | boolean | |
| &emsp;&emsp;pageSize | 页大小,默认为10 | | false | integer(int64) | |
| &emsp;&emsp;keyword | 搜索字符串 | | false | string | |
| token | Token Request Header | header | false | string | |
**响应状态**:
| 状态码 | 说明 | schema |
| ------ | ------------ | -------------------------------------- |
| 200 | OK | ApiResult«分页结果对象«OfflineMsgDto»» |
| 201 | Created | |
| 401 | Unauthorized | |
| 403 | Forbidden | |
| 404 | Not Found | |
**响应参数**:
| 参数名称 | 参数说明 | 类型 | schema |
| ---------------------------------------- | ------------------------------ | --------------------------- | --------------------------- |
| code | | integer(int32) | integer(int32) |
| message | | string | |
| data | | 分页结果对象«OfflineMsgDto» | 分页结果对象«OfflineMsgDto» |
| &emsp;&emsp;total | 总行数 | integer(int64) | |
| &emsp;&emsp;records | 数据列表 | array | OfflineMsgDto |
| &emsp;&emsp;&emsp;&emsp;msgId | 消息id | | false |
| &emsp;&emsp;&emsp;&emsp;createTime | 创建时间 | | false |
| &emsp;&emsp;&emsp;&emsp;withdrawTime | 撤回时间 | | false |
| &emsp;&emsp;&emsp;&emsp;sender | 发送者客户端id | | false |
| &emsp;&emsp;&emsp;&emsp;content | 内容 | | false |
| &emsp;&emsp;&emsp;&emsp;withdraw | 0未撤回; 1已撤回 | | false |
| &emsp;&emsp;&emsp;&emsp;event | 0非事件; 1为事件 | | false |
| &emsp;&emsp;&emsp;&emsp;system | 0非系统通知; 1为系统通知 | | false |
| &emsp;&emsp;&emsp;&emsp;at | at他人,传入客户端id数组 | | false |
| &emsp;&emsp;&emsp;&emsp;notReadCount | 未读人数统计,全部人已读为0 | | false |
| &emsp;&emsp;&emsp;&emsp;notReceiverCount | 未接收人数统计,全部人已接收为0 | | false |
| &emsp;&emsp;pageIndex | 页码 | integer(int64) | |
| &emsp;&emsp;pageSize | 页大小 | integer(int64) | |
**响应示例**:
```javascript
{
"code": 0,
"message": "",
"data": {
"total": 0,
"records": [
{
"msgId": 0,
"createTime": "",
"withdrawTime": "",
"sender": "",
"content": "",
"withdraw": true,
"event": true,
"system": true,
"at": "",
"notReadCount": 0,
"notReceiverCount": 0
}
],
"pageIndex": 0,
"pageSize": 0
}
}
```
## 离线消息列表
**接口地址**:`/api/imMessage/offlineList`
**请求方式**:`POST`
**请求数据类型**:`application/json`
**响应数据类型**:`*/*`
**接口描述**:
**请求参数**:
| 参数名称 | 参数说明 | in | 是否必须 | 数据类型 | schema |
| -------- | -------------------- | ------ | -------- | -------- | ------ |
| token | Token Request Header | header | false | string | |
**响应状态**:
| 状态码 | 说明 | schema |
| ------ | ------------ | --------------------------------------- |
| 200 | OK | ApiResult«List«ImMessageOfflineListVo»» |
| 201 | Created | |
| 401 | Unauthorized | |
| 403 | Forbidden | |
| 404 | Not Found | |
**响应参数**:
| 参数名称 | 参数说明 | 类型 | schema |
| ---------------------------------------- | ------------------------------ | -------------- | ---------------------- |
| code | | integer(int32) | integer(int32) |
| message | | string | |
| data | | array | ImMessageOfflineListVo |
| &emsp;&emsp;conversationId | 会话id | integer(int64) | |
| &emsp;&emsp;msgList | 消息列表 | array | OfflineMsgDto |
| &emsp;&emsp;&emsp;&emsp;msgId | 消息id | | false |
| &emsp;&emsp;&emsp;&emsp;createTime | 创建时间 | | false |
| &emsp;&emsp;&emsp;&emsp;withdrawTime | 撤回时间 | | false |
| &emsp;&emsp;&emsp;&emsp;sender | 发送者客户端id | | false |
| &emsp;&emsp;&emsp;&emsp;content | 内容 | | false |
| &emsp;&emsp;&emsp;&emsp;withdraw | 0未撤回; 1已撤回 | | false |
| &emsp;&emsp;&emsp;&emsp;event | 0非事件; 1为事件 | | false |
| &emsp;&emsp;&emsp;&emsp;system | 0非系统通知; 1为系统通知 | | false |
| &emsp;&emsp;&emsp;&emsp;at | at他人,传入客户端id数组 | | false |
| &emsp;&emsp;&emsp;&emsp;notReadCount | 未读人数统计,全部人已读为0 | | false |
| &emsp;&emsp;&emsp;&emsp;notReceiverCount | 未接收人数统计,全部人已接收为0 | | false |
**响应示例**:
```javascript
{
"code": 0,
"message": "",
"data": [
{
"conversationId": 0,
"msgList": [
{
"msgId": 0,
"createTime": "",
"withdrawTime": "",
"sender": "",
"content": "",
"withdraw": true,
"event": true,
"system": true,
"at": "",
"notReadCount": 0,
"notReceiverCount": 0
}
]
}
]
}
```
## 修改消息体
**接口地址**:`/api/imMessage/updateMsgById`
**请求方式**:`POST`
**请求数据类型**:`application/json`
**响应数据类型**:`*/*`
**接口描述**:只能修改客户端自己发送的消息
**请求示例**:
```javascript
{
"msgId": 0,
"content": {}
}
```
**请求参数**:
| 参数名称 | 参数说明 | in | 是否必须 | 数据类型 | schema |
| ------------------- | -------------------- | ------ | -------- | -------------- | ----------- |
| imMsgUpdate | imMsgUpdate | body | true | ImMsgUpdate | ImMsgUpdate |
| &emsp;&emsp;msgId | 消息id | | false | integer(int64) | |
| &emsp;&emsp;content | 内容 | | false | object | |
| token | Token Request Header | header | false | string | |
**响应状态**:
| 状态码 | 说明 | schema |
| ------ | ------------ | ------------------ |
| 200 | OK | ApiResult«boolean» |
| 201 | Created | |
| 401 | Unauthorized | |
| 403 | Forbidden | |
| 404 | Not Found | |
**响应参数**:
| 参数名称 | 参数说明 | 类型 | schema |
| -------- | -------- | -------------- | -------------- |
| code | | integer(int32) | integer(int32) |
| message | | string | |
| data | | boolean | |
**响应示例**:
```javascript
{
"code": 0,
"message": "",
"data": true
}
```
## 消息撤回
**接口地址**:`/api/imMessage/withdraw`
**请求方式**:`POST`
**请求数据类型**:`application/json`
**响应数据类型**:`*/*`
**接口描述**:只能撤回客户端自己发送的消息
**请求参数**:
| 参数名称 | 参数说明 | in | 是否必须 | 数据类型 | schema |
| -------- | -------------------- | ------ | -------- | -------------- | ------ |
| msgId | msgId | query | true | integer(int64) | |
| token | Token Request Header | header | false | string | |
**响应状态**:
| 状态码 | 说明 | schema |
| ------ | ------------ | ------------------ |
| 200 | OK | ApiResult«boolean» |
| 201 | Created | |
| 401 | Unauthorized | |
| 403 | Forbidden | |
| 404 | Not Found | |
**响应参数**:
| 参数名称 | 参数说明 | 类型 | schema |
| -------- | -------- | -------------- | -------------- |
| code | | integer(int32) | integer(int32) |
| message | | string | |
| data | | boolean | |
**响应示例**:
```javascript
{
"code": 0,
"message": "",
"data": true
}
```
# 消息收件箱表
## 消息修改为已读状态
**接口地址**:`/api/imInbox/msgReadUpdate`
**请求方式**:`POST`
**请求数据类型**:`application/json`
**响应数据类型**:`*/*`
**接口描述**:
**请求示例**:
```javascript
{
"msgIds": []
}
```
**请求参数**:
| 参数名称 | 参数说明 | in | 是否必须 | 数据类型 | schema |
| --------------------- | ------------------------------------------------------------ | ------ | -------- | --------------------- | --------------------- |
| imMsgReadStatusUpdate | imMsgReadStatusUpdate | body | true | ImMsgReadStatusUpdate | ImMsgReadStatusUpdate |
| &emsp;&emsp;msgIds | 消息id数组,可以传入单个或多个, 如接收离线消息列表时可以批量修改 则传入多个 | | false | array | integer |
| token | Token Request Header | header | false | string | |
**响应状态**:
| 状态码 | 说明 | schema |
| ------ | ------------ | ------------------ |
| 200 | OK | ApiResult«boolean» |
| 201 | Created | |
| 401 | Unauthorized | |
| 403 | Forbidden | |
| 404 | Not Found | |
**响应参数**:
| 参数名称 | 参数说明 | 类型 | schema |
| -------- | -------- | -------------- | -------------- |
| code | | integer(int32) | integer(int32) |
| message | | string | |
| data | | boolean | |
**响应示例**:
```javascript
{
"code": 0,
"message": "",
"data": true
}
```
## 消息修改为已接收状态
**接口地址**:`/api/imInbox/msgReceivedUpdate`
**请求方式**:`POST`
**请求数据类型**:`application/json`
**响应数据类型**:`*/*`
**接口描述**:
**请求示例**:
```javascript
{
"msgIds": [],
"readStatus": true
}
```
**请求参数**:
| 参数名称 | 参数说明 | in | 是否必须 | 数据类型 | schema |
| ---------------------- | ------------------------------------------------------------ | ------ | -------- | ------------------------- | ------------------------- |
| imMsgReceivedUpdate | imMsgReceivedUpdate | body | true | ImMsgReceivedStatusUpdate | ImMsgReceivedStatusUpdate |
| &emsp;&emsp;msgIds | 消息id数组,可以传入单个或多个, 如接收离线消息列表时可以批量修改 则传入多个 | | false | array | integer |
| &emsp;&emsp;readStatus | 是否同时修改为已读状态 | | false | boolean | |
| token | Token Request Header | header | false | string | |
**响应状态**:
| 状态码 | 说明 | schema |
| ------ | ------------ | ------------------ |
| 200 | OK | ApiResult«boolean» |
| 201 | Created | |
| 401 | Unauthorized | |
| 403 | Forbidden | |
| 404 | Not Found | |
**响应参数**:
| 参数名称 | 参数说明 | 类型 | schema |
| -------- | -------- | -------------- | -------------- |
| code | | integer(int32) | integer(int32) |
| message | | string | |
| data | | boolean | |
**响应示例**:
```javascript
{
"code": 0,
"message": "",
"data": true
}
```
# 终端
## 添加或修改推送设备信息(每次请求都会覆盖之前的数据)
**接口地址**:`/api/imClient/addDeviceInfo`
**请求方式**:`POST`
**请求数据类型**:`application/json`
**响应数据类型**:`*/*`
**接口描述**:
**请求示例**:
```javascript
{
"valid": 0,
"deviceType": 0,
"deviceToken": ""
}
```
**请求参数**:
| 参数名称 | 参数说明 | in | 是否必须 | 数据类型 | schema |
| ----------------------- | -------------------------------- | ------ | -------- | ---------------------- | ---------------------- |
| imClientDevice | imClientDevice | body | true | 添加或修改推送设备信息 | 添加或修改推送设备信息 |
| &emsp;&emsp;valid | 设备不想收到推送提醒, 1想, 0不想 | | false | integer(int32) | |
| &emsp;&emsp;deviceType | 设备类型1:ios; 2:android | | false | integer(int32) | |
| &emsp;&emsp;deviceToken | 设备推送token | | false | string | |
| token | Token Request Header | header | false | string | |
**响应状态**:
| 状态码 | 说明 | schema |
| ------ | ------------ | ------------------ |
| 200 | OK | ApiResult«boolean» |
| 201 | Created | |
| 401 | Unauthorized | |
| 403 | Forbidden | |
| 404 | Not Found | |
**响应参数**:
| 参数名称 | 参数说明 | 类型 | schema |
| -------- | -------- | -------------- | -------------- |
| code | | integer(int32) | integer(int32) |
| message | | string | |
| data | | boolean | |
**响应示例**:
```javascript
{
"code": 0,
"message": "",
"data": true
}
```
## 获取用户在线状态(批量)
**接口地址**:`/api/imClient/onlineStatus`
**请求方式**:`POST`
**请求数据类型**:`application/json`
**响应数据类型**:`*/*`
**接口描述**:
**请求示例**:
```javascript
{
"clientIds": []
}
```
**请求参数**:
| 参数名称 | 参数说明 | in | 是否必须 | 数据类型 | schema |
| --------------------- | -------------------- | ------ | -------- | -------------------- | -------------------- |
| getOnlineStatusParam | getOnlineStatusParam | body | true | GetOnlineStatusParam | GetOnlineStatusParam |
| &emsp;&emsp;clientIds | 客户端ID | | false | array | string |
| token | Token Request Header | header | false | string | |
**响应状态**:
| 状态码 | 说明 | schema |
| ------ | ------------ | --------------------------------- |
| 200 | OK | ApiResult«List«ImOnlineStatusVo»» |
| 201 | Created | |
| 401 | Unauthorized | |
| 403 | Forbidden | |
| 404 | Not Found | |
**响应参数**:
| 参数名称 | 参数说明 | 类型 | schema |
| -------------------- | ----------------------- | -------------- | ---------------- |
| code | | integer(int32) | integer(int32) |
| message | | string | |
| data | | array | ImOnlineStatusVo |
| &emsp;&emsp;status | true:在线, false 不在线 | boolean | |
| &emsp;&emsp;clientId | | string | |
**响应示例**:
```javascript
{
"code": 0,
"message": "",
"data": [
{
"status": true,
"clientId": ""
}
]
}
```
# 获取sign(Demo)
## 获取sign(仅测试使用)
**接口地址**:`/api/signDemo/get`
**请求方式**:`GET`
**请求数据类型**:`*`
**响应数据类型**:`*/*`
**接口描述**:生成签名
**请求示例**:
```javascript
{
"timestamp": "",
"clientId": "",
"appKey": "",
"appSecret": ""
}
```
**请求参数**:
| 参数名称 | 参数说明 | in | 是否必须 | 数据类型 | schema |
| --------------------- | -------------------- | ------ | -------- | ------------ | ------------ |
| getSignParam | getSignParam | body | true | GetSignParam | GetSignParam |
| &emsp;&emsp;timestamp | 时间戳 | | false | string | |
| &emsp;&emsp;clientId | client客户端id | | false | string | |
| &emsp;&emsp;appKey | appKey | | false | string | |
| &emsp;&emsp;appSecret | 密钥 | | false | string | |
| token | Token Request Header | header | false | string | |
**响应状态**:
| 状态码 | 说明 | schema |
| ------ | ------------ | ------ |
| 200 | OK | |
| 401 | Unauthorized | |
| 403 | Forbidden | |
| 404 | Not Found | |
**响应参数**:
暂无
**响应示例**:
```javascript
```
# 黑名单
## 拉入黑名单
**接口地址**:`/api/ClientBlacklist/add`
**请求方式**:`POST`
**请求数据类型**:`application/json`
**响应数据类型**:`*/*`
**接口描述**:
**请求示例**:
```javascript
{
"clientIdBePrevent": ""
}
```
**请求参数**:
| 参数名称 | 参数说明 | in | 是否必须 | 数据类型 | schema |
| ----------------------------- | ----------------------- | ------ | -------- | ----------------------- | ----------------------- |
| imClientBlacklistUpdate | imClientBlacklistUpdate | body | true | ImClientBlacklistUpdate | ImClientBlacklistUpdate |
| &emsp;&emsp;clientIdBePrevent | 被拉黑者id | | false | string | |
| token | Token Request Header | header | false | string | |
**响应状态**:
| 状态码 | 说明 | schema |
| ------ | ------------ | ------------------ |
| 200 | OK | ApiResult«boolean» |
| 201 | Created | |
| 401 | Unauthorized | |
| 403 | Forbidden | |
| 404 | Not Found | |
**响应参数**:
| 参数名称 | 参数说明 | 类型 | schema |
| -------- | -------- | -------------- | -------------- |
| code | | integer(int32) | integer(int32) |
| message | | string | |
| data | | boolean | |
**响应示例**:
```javascript
{
"code": 0,
"message": "",
"data": true
}
```
## 移出黑名单
**接口地址**:`/api/ClientBlacklist/delete`
**请求方式**:`POST`
**请求数据类型**:`application/json`
**响应数据类型**:`*/*`
**接口描述**:
**请求示例**:
```javascript
{
"clientIdBePrevent": ""
}
```
**请求参数**:
| 参数名称 | 参数说明 | in | 是否必须 | 数据类型 | schema |
| ----------------------------- | ----------------------- | ------ | -------- | ----------------------- | ----------------------- |
| imClientBlacklistUpdate | imClientBlacklistUpdate | body | true | ImClientBlacklistUpdate | ImClientBlacklistUpdate |
| &emsp;&emsp;clientIdBePrevent | 被拉黑者id | | false | string | |
| token | Token Request Header | header | false | string | |
**响应状态**:
| 状态码 | 说明 | schema |
| ------ | ------------ | ------------------ |
| 200 | OK | ApiResult«boolean» |
| 201 | Created | |
| 401 | Unauthorized | |
| 403 | Forbidden | |
| 404 | Not Found | |
**响应参数**:
| 参数名称 | 参数说明 | 类型 | schema |
| -------- | -------- | -------------- | -------------- |
| code | | integer(int32) | integer(int32) |
| message | | string | |
| data | | boolean | |
**响应示例**:
```javascript
{
"code": 0,
"message": "",
"data": true
}
```
## 黑名单分页列表
**接口地址**:`/api/ClientBlacklist/getPageList`
**请求方式**:`POST`
**请求数据类型**:`application/json`
**响应数据类型**:`*/*`
**接口描述**:
**请求示例**:
```javascript
{
"pageIndex": 1,
"pageSorts": [
{
"column": "",
"asc": true
}
],
"pageSize": 10,
"keyword": ""
}
```
**请求参数**:
| 参数名称 | 参数说明 | in | 是否必须 | 数据类型 | schema |
| ------------------------------ | -------------------------- | ------ | -------- | -------------- | -------------- |
| imClientBlacklistPageParam | imClientBlacklistPageParam | body | true | 黑名单分页参数 | 黑名单分页参数 |
| &emsp;&emsp;pageIndex | 页码,默认为1 | | false | integer(int64) | |
| &emsp;&emsp;pageSorts | 排序 | | false | array | OrderItem |
| &emsp;&emsp;&emsp;&emsp;column | | | false | string | |
| &emsp;&emsp;&emsp;&emsp;asc | | | false | boolean | |
| &emsp;&emsp;pageSize | 页大小,默认为10 | | false | integer(int64) | |
| &emsp;&emsp;keyword | 搜索字符串 | | false | string | |
| token | Token Request Header | header | false | string | |
**响应状态**:
| 状态码 | 说明 | schema |
| ------ | ------------ | ----------------------------------------------------- |
| 200 | OK | ApiResult«分页结果对象«ImClientBlacklistQueryVo对象»» |
| 201 | Created | |
| 401 | Unauthorized | |
| 403 | Forbidden | |
| 404 | Not Found | |
**响应参数**:
| 参数名称 | 参数说明 | 类型 | schema |
| ----------------------------------------- | ---------- | ------------------------------------------ | ------------------------------------------ |
| code | | integer(int32) | integer(int32) |
| message | | string | |
| data | | 分页结果对象«ImClientBlacklistQueryVo对象» | 分页结果对象«ImClientBlacklistQueryVo对象» |
| &emsp;&emsp;total | 总行数 | integer(int64) | |
| &emsp;&emsp;records | 数据列表 | array | ImClientBlacklistQueryVo对象 |
| &emsp;&emsp;&emsp;&emsp;clientIdBePrevent | 被拉黑者id | | false |
| &emsp;&emsp;pageIndex | 页码 | integer(int64) | |
| &emsp;&emsp;pageSize | 页大小 | integer(int64) | |
**响应示例**:
```javascript
{
"code": 0,
"message": "",
"data": {
"total": 0,
"records": [
{
"clientIdBePrevent": ""
}
],
"pageIndex": 0,
"pageSize": 0
}
}
```
\ No newline at end of file
# wecloud-im服务端REST API对接文档
# wecloud-im服务端REST API对接文档
## 本地API文档地址
http://192.168.1.110:8082/api/doc.html#/home
账号密码admin admin
以上只包含api接口文档 websocket对接说明在此文档中
## 测试外网
文档:
```
https://wstest.im199.com/api/doc.html#/home
```
___
测试外网请求示例:
```
https://wstest.im199.com/api/imApplication/add
```
___
ws连接示例
```
wss://wstest.im199.com/ws?token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJhdWQiOiJ3ZWIiLCJjbGllbnRJZCI6ImFiY2QxIiwiaXNzIjoid2VjbG91ZF9pbSIsImFwcEtleSI6IkpLdE5IZnJWVXdzaGF4ek4iLCJleHAiOjE2MjgzMjMxNDMsImlhdCI6MTYyMzEzOTE0MywianRpIjoiNWU3NzU5ZjM2ODQ3NDFiMzg4MGEyYjkwMjQ0OWZjZmYifQ.CC-iuGjNwQLH4VxFI2wZEPuP4AGabOUOiRh9snp3IB4
```
_______
## 生产环境
ws.im199.com
文档:
```
https://ws.im199.com/api/doc.html#/home
```
___
测试外网请求示例:
```
https://ws.im199.com/api/imApplication/add
```
___
ws连接示例
```
wss://ws.im199.com/ws?token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJhdWQiOiJ3ZWIiLCJjbGllbnRJZCI6ImFiY2QxIiwiaXNzIjoid2VjbG91ZF9pbSIsImFwcEtleSI6IkpLdE5IZnJWVXdzaGF4ek4iLCJleHAiOjE2MjgzMjMxNDMsImlhdCI6MTYyMzEzOTE0MywianRpIjoiNWU3NzU5ZjM2ODQ3NDFiMzg4MGEyYjkwMjQ0OWZjZmYifQ.CC-iuGjNwQLH4VxFI2wZEPuP4AGabOUOiRh9snp3IB4
```
_______
## 鉴权方式
### 方式一:
对于 POST 和 PUT 请求,请求的主体必须是 JSON 格式,而且 HTTP header 的 Content-Type 需要设置为 `application/json`
用户验证通过 HTTP header 来进行,**X-LC-Id** 标明正在运行的是哪个应用(应用的 App ID), **X-LC-Key** 用来授权鉴定 endpoint:
```json
curl -X PUT \
-H "X-LC-Id: {{appid}}" \
-H "X-LC-Key: {{appkey}}" \
-H "Content-Type: application/json" \
-d '{"content": "更新一篇博客的内容"}' \
https://https://ws.im199.com/api/
```
**X-LC-Key** 通常情况下是应用的 App Key
### 方式二
**更安全的鉴权**
我们还支持一种新的 API 鉴权方式,即在 HTTP header 中使用 **X-LC-Sign** 来代替 **X-LC-Key**,以降低 App Key 的泄露风险。例如:
```json
curl -X PUT \
-H "X-LC-Id: {{appid}}" \
-H "X-LC-Sign: d5bcbb897e19b2f6633c716dfdfaf9be,1453014943466" \
-H "Content-Type: application/json" \
-d '{"content": "在 HTTP header 中使用 X-LC-Sign 来更新一篇博客的内容"}' \
https://https://ws.im199.com/api/
```
**X-LC-Sign** 的值是由 `sign,timestamp` 组成的字符串:
| 取值 | 约束 | 描述 |
| :-------- | :--- | :----------------------------------------------------------- |
| sign | 必须 | 将 timestamp 加上 App Key 组成的字符串,再对它做 MD5 签名后的结果。 |
| timestamp | 必须 | 客户端产生本次请求的 unix 时间戳(UTC),精确到**毫秒**。 |
举例来说,假设应用的信息如下:
| App Id | `FFnN2hso42Wego3pWq4X5qlu` |
| ---------- | --------------------------------- |
| App Key | `UtOCzqb67d3sN12Kts4URwy8` |
| 请求时间 | 2016-01-17 15:15:43.466 GMT+08:00 |
| timestamp | `1453014943466` |
**使用 App Key 来计算(MD5) sign**:
```sh
-H "X-LC-Sign: d5bcbb897e19b2f6633c716dfdfaf9be,1453014943466" \
```
## 响应格式
对于所有的请求,响应格式都是一个 JSON 对象。
一个请求是否成功是由 HTTP 状态码标明的。一个 2XX 的状态码表示成功,而一个 4XX 表示请求失败。当一个请求失败时响应的主体仍然是一个 JSON 对象,但是总是会包含 `code``error` 这两个字段,你可以用它们来进行调试。举个例子,如果尝试用非法的属性名来保存一个对象会得到如下信息:
## 单聊、群聊
### 创建对话
### 查询对话
### 更新对话
### 删除对话
### 增加成员
### 移除成员
### 查询成员
### 单聊、群聊-发消息
### 查询历史消息
### 单聊、群聊-修改消息
### 单聊、群聊-撤回消息
## 黑名单
### 增加对话黑名单
### 移除对话黑名单
### 查询对话黑名单
......@@ -19,7 +19,7 @@ aaaaa3
--
-- 会话
## 会话
1邀请2
1427910060675305472
......@@ -78,13 +78,13 @@ load-blance:
server-type: Local
2021年09月27日17:00:50部署国内IM集成版
## 2021年09月27日17:00:50部署国内IM集成版
部署1.3 版本
| weikeyun_imapi | 121.37.208.9 | 国内IM集成版
docker run -p 6379:6379 -d --restart=always --name redis6 -v $PWD/dockerData/redis6:/data redis:6 --appendonly yes --requirepass "axT8knPN5hAP"
##mysql5.7(如果本地不开,可以连上测试环境)
## mysql5.7(如果本地不开,可以连上测试环境)
### docker 安装mysql
docker run -p 3306:3306 --name mysql57 -v $PWD/dockerData/mysql57/data:/var/lib/mysql --restart always -e MYSQL_ROOT_PASSWORD=JH86uc53r8Ca -d mysql:5.7
mysql
......@@ -97,5 +97,25 @@ mysql
port: 6379
utf8mb4_unicode_ci
建库语句
## 建库语句
CREATE DATABASE IF NOT EXISTS wecloud_im DEFAULT CHARSET utf8mb4 COLLATE utf8mb4_general_ci;
## 单人RTC设计思路 , 2021年10月08日 周五
1. 引入"频道RtcChannel"概念, 可以不基于会话发起音视频通话
2. 不在同个会话中的两个client加入到同一个频道进行通话 (可配置是否两个client必须在同一个会话才能发起音视频通话)
3. 目前频道只支持两个client,进行通话的两端必须先加入到同一个"频道",所有的指令都在频道内进行转发
4. 一个频道可以由通话发起者绑定到会话ID,"挂断","未接听"等状态会同步到会话, 未绑定将不同步到会话(可选)
5. 连接websocket时带上client类型, 如web,安卓,ios
client需要监听频道内 状态更新(房间断开 .挂断)、用户状态更新(用户加入, 用户退出)、流状态更新(切换音频 切换视频)
## 创建频道请求参数
接收者id (数组)
扩展参数(Object)
### 响应参数
频道id
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment