# 1. 启动

## 1.1. 初始化

### 1.1.1 移动端

> 获取设备信息，生成设备唯一码，注册推送服务获取pushToken

> 避免应用权限等问题，`设备唯一码`使用自主生成，本地缓存的方式处理。
>
> sdk初始化时，读取`设备唯一码`缓存，如果存在则直接使用，如果不存在则重新生成并且保存。

### 1.1.2 web端

> 获取设备信息，获取唯一码。目的区分登录设备。

## 1.2. 注册服务

> 客户端用户登录之后，使用`userId`调用sdk注册接口，获取`account`以及`IM服务器信息`。然后订阅该`account`对应的消息通道
>
> 这一步，可以定义一些非必传信息，比如`userName`一类，后续用户数据展示的时候方便一些。

> 服务端根据设备类型(type)、唯一码(uuid)、userId等信息，生成对应account。
>
> 1.`type`和`uuid`都一样，但是`userId`不同，代表用户同一设备切换了登录用户。重新生成account，之前的account需要废除。
>
> 2.`userId`相同，`type`或`uuid`不同，代表同一用户，在不同设备登录。这时需要发送异地登录消息。

> 移动端注册服务时，需要配置是否需要互踢，(同类型设备互踢、所有设备互踢)-----这个配置放在哪里比较合适？
>
> 这配置主要用来服务端注销推送服务，互踢的情况下，后登录的app端可以收到推送，前面登录的收不到。
>
> 真实的互踢功能，需要客户端根据`异地登录消息`自行开发。

# 2. 发送消息

## 2.1. 基础消息

> 客户端调用sdk发消息的api。sdk封装消息体，与服务端交互。
>
> `单聊`:直接转发；`群聊`：服务端改变消息体结构，轮询转发。
>
> 服务端对消息做转发处理。`存档`、`屏蔽词`等在这里处理。
>
> `推送相关操作在这里进行`
>
> 如果存在需要改变状态的消息，可以发送自定义消息，自定义消息体，判断id是否相同。
>
> sdk收到消息后，app端存表，之后发出消息到达通知，其它端直接发送通知。
>
> 通知需携带消息内容
>
> 需要考虑，推送机制，聊天消息，是否每条都要发送推送。
>
> 或者考虑sdk开放配置，客户端决定自己的推送时机

## 2.2 应用消息、广播通知、后台变更等消息

>这一类消息大多是第三方服务直接构建消息体，调用服务端api发送。
>
>服务端需要做应用维护，分发appId，做autoToken生成机制，用来调用接口

> 这一类消息产生的需求，单人推送和群推送，需要服务端暴漏接口，用来做群组，成员标签相关的处理。

> 应用消息和通知类，是需要做推送的。
>
> 需要用户定义消息栏点击操作，打开应用，跳转指定页面，打开网页等。

## 2.3 历史消息、离线消息

> 历史消息是一个时间段查询，随意定义开始结束时间，可以选择指定成员。

> 离线消息，是截至某一时间之后的所有新消息，需要前端维护这个差分时间。

# 3.注销、停用推送

## 3.1注销

> 使用场景大多为，用户退出登录、客户端切换账号等。
>
> 切换账号客户端需要维护，但是服务端需要判断设备唯一码与userId的关系，避免一台机器同时收到两个用户的消息。

## 3.2启停推送

> 考虑一个场景，用户想要主动关闭推送的话，给一个配置。
>
> 延伸出一个场景，免打扰模式，定义时间段内不接受推送。

# 4.日志收集

> 日志部分，可以使用im直接传输到服务端。

# 5.数据库

> app端sdk，考虑集成数据库模块，提高相应速率，增加容错率。
>
> 比如用户单聊，打开页面直接就可以看到数据。省区调用接口的时间。

# 6.音视频聊天

> 使用声网sdk完成，做成独立模块，后续如果需要更换，可以直接拔插。
>
> 以单聊举例：
>
> ​	a对b发起视频聊天，sdk所做的事情为：生成一个声网房间号，a用户加入该房间，发送im邀请通知。
>
> ​	b用户收到通知后，弹出邀请界面，如果接通，则直接进入消息携带的房间号，完成通话。
>
> ​	拒绝，超时等场景，根据实际情况设计。

# 7.UI

> 考虑选择图片、选择文件、音视频通话，sdk定义一套基础页面，客户端可以选择直接使用，或者自定义UI界面。















# ***是否做保活***

> 应用自启，后台进程锁引导等



































