Commit 9c7c59d3 by giaogiao

优化文档, 增加外部对接文档

parent a1d88fd2
# 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 即时通讯云对接文档
# wecloud-im 即时通讯云对接文档
[TOC]
## 使用场景
即时通讯服务现在已经被广泛使用**在应用内社交、工作协同、客服系统、超大型赛事和电视直播、以及游戏状态同步**等多种业务场景之中。
即时通讯是主要**解决产品内聊天**即时通信(Instant Messaging)、实时数据同步等需求,其设计上的主要目标是:
- **支持为现有应用快速加入多种通讯能力**
我们很多客户的产品都已经达到一个比较稳定的形态,即时通讯只是其中一个锦上添花的功能,所以如何和现有系统无缝集成,是我们设计上一个重要的出发点。即时通讯服务可以在应用账户系统独立的情况下,快速接入并稳定安全地运行。
我们支持了多种典型通讯场景,提供了UI 库和脚手架来帮助开发者快速接入。并且考虑到业务运行环境,我们提供了支持的 SDK。
- **强大的自定义机制满足业务各种扩展需求**
我们默认支持了**文本、图片、音视频、地理位置**等多种类型的消息收发,同时也允许产品开发者来扩展自己的消息类型和 UI 样式。并且在基本功能之外,我们也支持更多高阶需求,例如消息撤回与修改、@ 成员提醒、暂态消息、「已读」回执、离线推送、敏感内容过滤等等与消息收发相关的功能在这里都可以得到满足。
- **安全和权限控制**
我们始终把系统安全性放在首要位置,客户端与云端使用 WebSocket 全双工通讯,全程 TLS 加密传输。在用户登录和操作权限的控制上,我们专门设计了第三方操作签名的机制,让应用层在快速接入的同时,也可以实时、完整地控制用户在即时通讯系统内的所有活动。在群聊和开放聊天室等业务场景里,我们也提供了成员角色管理和黑名单的机制,以满足产品运营管理的多样需求。
- **最大限度降低客户的生产运维成本**
我们提供专业的技术支持服务,富有经验的资深工程师 7 × 24 小时对接,以帮助开发者快速、有效地完成产品集成,缩短开发周期。此外在产品运营阶段,让开发者彻底摆脱后端系统日常的运维细节和突发的软硬件故障处理,也不用关心用户量和流量的变化。帮助客户在享受高品质技术服务的同时,也可以最大限度降低生产运维成本,并且以更快的速度推进产品迭代,是我们始终追求的目标。
## 功能和特性
即时通讯服务提供的主要功能有:
- **基本聊天功能**,包括:
- 支持多种聊天场景。除了普通的单聊、群聊
- 用户之间可以发送多种多样的消息,如文本、图片、语音、音视频、地理位置等,以及更多的应用层自定义消息。
- 聊天消息自动保存在云端,可选支持永久消息存储,支持各种复杂的查找和翻页方式。
- **特殊的消息收发需求**。除了普通的消息收发之外,我们还支持:
- 带有提醒功能的 **@ 消息**(如微信里面的 @ 某人)
- 消息的 **撤回和修改**
- 消息送达和对方已读的 **回执通知**
- 群聊里面为了避免过于干扰,允许用户开启 **消息免打扰** 开关
- 在消息接收方离线时,自动转为 **系统推送通知,ios和安卓**(Push Notification)
- **安全控制**
任何终端用户要开启即时通讯服务,只需要提供一个唯一标识自己的 `clientId` 即可,不需要传入任何用户数据,以保证信息不被泄露,这种与产品自有账户系统解耦合的方式,带来了集成的便利,也可以促使通讯服务商专注做好底层的「信使」角色。 同时我们也提供 **第三方鉴权** 的机制,通过在聊天流程中加入开发者服务器签名授权这一环节,来确保通讯操作的安全。 而且,即时通讯 SDK 与云端是 WebSocket 全双工通讯,且全程使用 TLS 安全加密。
- **强大的业务扩展能力**
对于很多典型的需求,我们提供了默认的实现,而为了支持业务的多样性和特殊性,我们也提供了丰富的扩展机制:
- 为了和产品自有用户系统进行对接,我们提供了第三方操作鉴权的扩展接口,确保在用户登录、创建/加入/退出对话群组、以及拉取聊天记录时,所有操作都得到了授权。
- 同时我们还支持开发者对消息传递的过程进行 **hook 处理**,在消息到达云端但是还没有投递之前和投递之后,分别完成自定义的处理逻辑,例如过滤掉竞品的品牌,以及自定义离线推送消息,等等。
- 我们也支持通过简单的 **web hook** 来完成云端和应用后端的消息同步。
- 在提供移动端的 SDK 之外,我们还提供了 REST API,以帮助产品在可信环境下更好地实现业务处理。
**我们相信灵活性和扩展性也是云服务的核心竞争力。**
## 核心概念说明
### clientId、用户和登录
即时通讯服务中的每一个终端称为一个「Client」。Client 拥有一个在应用内唯一标识自己的 ID(`clientId`)。这个 ID 由应用自己定义,必须是 **由任意英文字母、数字、半角下划线与半角短横线组成,可以纯数字,不超过 64个字符的字符串组成**。在大部分场合,Client 都可以对应到应用中的某个「用户」,但是并不是只有真的用户才能作为「Client」,你完全可以把一个探测器当成一个「Client」,把它收集到的数据通过即时通讯服务广播给更多「人」。
要使用即时通讯服务,每一个终端设备需要首先建立与即时通讯云服务端的 WebSocket 长连接,并使用唯一的 `clientId` 来加入即时通讯服务,我们把这一过程称为「登录」。请注意这里的登录仅仅指客户端登录即时通讯服务,与应用层面的用户账户注册登录是不一样的。
### appKey与appSecret
appKey为应用在蔚可云的唯一标识, appSecret为安全密钥, 均由蔚可云控制台或联系客服下发,给应用接入方安全验证密钥,生产环境appSecret不建议保存在接入方前端客户端, appKey与appSecret总是成对出现和使用
### 生成sign签名
sign 由接入方后端生成, 进行加签的参数: MD5{timestamp + clientId + appKey + appSecret}
timestamp:毫秒时间戳
clientId:由后端生成
**在生产环境中,你需要自行部署服务器签发 sign**
### 对话(Conversation)
用户登录之后,与其他人(client)进行消息沟通,即为开启了一个「对话(Conversation)」。在即时通讯服务中,「对话」包含了沟通的用户群体(成员),也是所有消息依托的媒介:消息都是由某一个 Client 发往一个「对话」。终端用户在开始聊天之前,需要先创建或者加入一个对话,然后再邀请其他人进来(可选),之后所有参与者在这个对话内进行交流。
### 已读/已接收
**已接收**为客户端接收到该消息,已经保存到本地缓存中,用户还未打开会话查看该条消息的情况. 服务器将不会再次下发已接收状态的离线消息,未接收的消息会在拉取离线消息时返回
**已读**为客户端已经查看该消息
## 业务场景的需求
在解释对话类型之前,我们先列举一下即时通讯可能的使用场景。
- 单聊/私聊
就是两个 Client 之间的对话,公开与否(能否让其他人看到这个对话存在)由应用层自己控制。通常的业务场景里它是私密的,并且加入新的成员之后,会切换成新的群聊(当然,也可以依然不离开当前对话,这一点还是由应用层来决定), 可选两个client之间只能存在一个会话。
- 群聊
就是两个(含)以上 Client 之间的对话,通常可以添加和删除成员,并且会赋予群聊一个名字,例如「家人群」、「朋友群」、「部门同事群」等等。随着成员的减少,群聊也可能只有两个甚至一个成员(成员的多少并不是区分群聊和单聊的关键)。群聊能否公开(譬如支持名字搜索),由应用自己决定。
## 客户端连接流程
![wc_im_client连接流程-Page-1](https://tva1.sinaimg.cn/large/008i3skNly1gvv3zjcuajj30zt0u0div.jpg)
1. appKey, appSecret为蔚可云下发给客户方安全保护密钥,不建议保存在前端客户端;
2. 第三方应用服务端需提供获取sign的接口, sign 由MD5{timestamp + clientId + appKey + appSecret},其中clientId由后端生成;
3. 前端拿到sign后,调用验证sign接口进行获取token;
4. websocket连接初始化需要带上token即可连接成功;
5. sign 需要在你的应用服务端生成;
### 第三方应用后端生成sign接口示例
本文展示如何在服务端部署一个 sign 生成器。
**java**示例代码 ,供客户应用后端参考
```java
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);
}
```
第三方应用后端**必须**要响应给前端的参数:
```json
{
"timestamp": "1628838135066",
"clientId": "client_3334444",
"appKey": "D13ug9jsWbJbeVx1",
"sign": "c15a886fe4114dba2c8f078369e6bec9"
}
```
# wecloud-im 视频通话云对接文档
# wecloud-im 视频通话云对接文档
[TOC]
## 产品概述
集成视频 SDK,实现高清流畅视频通话。
视频通话 SDK 可实现一对一视频通话,同时具备纯语音通话和视频通话功能。
**即将推出多对多视频通话**
## 使用场景
##### 视频聊天
支持 1 对 1 视频通话,适用于视频聊天、视频客服、远程医疗、金融双录、远程定损等场景
##### 在线教育
视频面对面教学,真实还原线下教学场景,支持 1v1 教学
##### 视频客服
支持 1v1 专属 VIP 视频客服,助力用户服务升级,提供更优质的服务体验
**即将推出多对多视频通话**
## 文档描述
此文档为一对一音视频通话技术对接文档
由于视频通话基于wecloud-im聊天服务,**对接视频通话前,需要先对接wecloud-im聊天服务**
## 核心概念说明
### 频道
两个client加入到同一个"频道"进行音视频通话
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