Files
rw0067680 c01808ac21 first commit
Change-Id: Ib7c2ab10a2562044fcaf9879388a6cbc1db6ac61
2025-12-23 10:00:49 +08:00

217 lines
15 KiB
Plaintext
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
## 接入推送流程
1. 申请厂商推送服务
2. 移动端配置
3. 配置和部署推送服务(push-server)
4. IM-Server 配置
5. 推送测试
6. 调试推送服务
7. 问题排查
### 一,申请厂商推送服务
目前支持小米、华为、vivo、oppo、魅族、苹果等推送需要到各个厂商的开发者后台申请推送相关 key
### 二,移动端配置
#### Android 端配置
Android端推送相关的代码都在```push module``` 下面,入口是```PushService```,配置之后,如果能调用```ChatManager#setDeviceToken```,则表示配置成,下面是具体的配置
1. 修改```push/build.gradle```下推送相关配置信息,如下:
```
// 默认配置的 appid 和 appkey 不可以直接使用
manifestPlaceholders = [
MI_APP_ID : "2882303761517722456",
MI_APP_KEY : "5731772292456",
HMS_APP_ID : "100221325",
MEIZU_APP_ID : "113616",
MEIZU_APP_KEY: "fcd886f51c144b45b87a67a28e2934d1",
VIVO_APP_ID : "12918",
VIVO_APP_KEY : "c42feb05-de6c-427d-af55-4f902d9e0a75",
OPPO_APP_KEY : "16c6afe503b24259928e082ef01a6bf2",
OPPO_APP_SECRET : "16c6afe503b24259928e082ef01a6bf2"
]
```
2. 华为推送需要```chat/agconnect-services.json```文件,该文件是华为推送后台生成的
3. FCM推送需要替换```push/google-services.json```文件,该文件是 FCM 推送后台生成的
4. 如果一切正常,启动 App 之后,会打印下面这一行日志,**如果没有打印该日志,则说明配置错误,请查看日志,或者在```PushService```打断点调试**
```
Log.d(TAG, "setDeviceToken" + token + " " + pushType);// 这是打印日志的代码!!
```
5. 如果不需要某些推送类型,可以将其从```push module```删除,保留也不影响
6. 如果需要使用个推,请看```getui```分支
#### iOS 端配置
请参考[ios-chat](https://github.com/wildfirechat/ios-chat)项目```appdelegate.m```文件中的关于推送注册的部分。当调用到```setDeviceToken```方法传入推送token即为客户端接入成功。
### 三,配置和部署推送服务
1. 修改配置
本推送服务有1个工程配置文件和7个推送配置文件都在工程的```config```目录下,请根据实际情况配置服务的端口和各个推送服务配置,推送服务配置一定要和移动端对应上,别配置成不同的 app 去了。
如果有无法支持的推送类型,请修改客户端去掉不支持的类型(注意这里的配置文件要保留)。
2. 配置证书
苹果和谷歌推送需要证书,请把对应证书分别放到```apns```和```fcm```目录下,然后修改配置文件中的证书路径。
3. 编译
```
mvn package
```
4. 运行
编译成功之后,在```target```目录找到```push-xxxx.jar```然后把jar包、```config```目录、```apns```和```fcm```目录放到一起,然后执行下面命令:
```
nohup java -jar push-xxxx.jar 2>&1 &
```
### 四IM-Server 配置
修改IM服务的配置文件```wildfirechat.conf```,指向推送服务器的地址,修改完后需要重启
```
#*********************************************************************
# Push server configuration
#*********************************************************************
##安卓推送服务器地址
push.android.server.address http://localhost:8085/android/push
##苹果推送服务器地址
push.ios.server.address http://localhost:8085/ios/push
```
### 五,推送测试
1. 确保双方都在线时,能互发消息
2. Android端为了保证用户能正常收到消息需要进行一些相关设置产品上线之后也需要引导用户进行相关设置不设置会收到不到推送具体设置方式不同手机不一样请参考具体的手机设置也可以参考[这儿](https://docs.rongcloud.cn/im/push/android/message_notification/)
1. 允许后台运行
2. 允许自启动
3. 允许后台弹出界面
4. 允许显示通知
3. 将其中一方杀进程,另外一方向其发送文本消息
4. 查看被杀进程一方,是否收到推送
### 六,调试推送服务
推送厂商SDK可能随时更新接口也有可能由变更推送服务和客户端推送SDK可能需要更新和调整。也有可能推送厂商开发后台配置错误导致无法推送成功。出现这种情况后请按照对应厂商的最新说明调试推送服务。推送服务收到IM服务推送请求后调用厂商SDK进行推送这部分工作与野火IM无关了请仔细阅读推送厂商的文档或者与联系推送厂商的技术支持。
### 七,问题排查
如果遇到问题请按照以下步骤排查:
1. 请确保上面所有步骤都正确完成之后,再开始问题排查
2. 确保程序是非启动状态,如果退回到桌面,应用还是激活的还会继续收消息,此时就不会走推送服务。应用在后台激活状态时应该走本地通知。
3. 确认客户端推送SDK是否正确的获取到token是否调用了```setDeviceToken``````token```和```type```是多少?
4. 上一步成功之后,```IM-Server```数据库的```t_user_session```表的```_token```和```_push_type```字段会被填上上一步设置的值。
5. 确认消息是否是自定义消息,如果是自定义消息,```push content```或者```push data```至少一个不为空才会推送。另外消息的[PersistFlag](https://docs.wildfirechat.cn/base_knowledge/message_content.html#消息类型)必须是存储或者存储计数属性的才会推送。
6. 确认目标客户端是否7日之内登录过超过7天是不推送的。
7. 确认目标客户是否设置了全局静音或会话静音。
8. 如果有pc和web端登陆确认是否设定了pc在线时手机静音。
9. 查看```IM-Server```日志,看是否有推送相关日志输出
```
LOG.info("Send push to {}, message from {}", deviceId, sender); // 这是打印日志的代码!!
```
10. 确认推送服务是否收到了推送信息如果收到token和type是否和步骤1一致推送内容是否和2一致
```
// 目标用户是 Android
LOG.info("Android push {}", new Gson().toJson(pushMessage)); // 这是打印日志的代码
// 目标用户是 iOS
LOG.info("iOS push {}", new Gson().toJson(pushMessage)); // 这是打印日志的代码
```
11. 推送服务收到IM请求的推送信息调用厂商SDK进行推送检查代码确认是透传方式还是通知栏方式。
12. 如果推送服务使用的是通知栏方式,后面的工作就全是推送厂商的工作了,请按照推送厂商的官方文档进行调试。
13. 如果推送服务使用的是透传方式请确认客户端对应推送SDK是否收到透传消息如果没有收到透传消息则问题出在推送通道上请按照推送厂商的官方文档进行调试。
14. 如果推送服务使用的是透传方式确认对应推送SDK收到了透传消息请检查应用激活后是否初始化IM SDK并调用connect方法及连接状态是否连接成功是否收到新消息是否弹出本地通知。
### 技术支持
按照文档一般情况下都能成功处理推送功能。实际上推送的功能并不复杂,只是涉及到太多的环节,每个环节又是由不同的研发或者公司来负责。请一定要理解整个推送的过程,知道推送过程中每一环节的功能,每个环节由谁来负责或者检查,只有真正的理解了推送的完整流程,才能找到对应的人来处理,才有可能高效地处理推送问题。
当确认是野火负责的环节时可以来给野火提issue或者论坛发帖问。提问时请写清楚下面几个要求
1. 请写出推送的完整流程。
2. 请写出推送的每个环节是那一方来负责比如android端注册推送并调用setDeviceToken由你们android研发来负责。
3. 你认为那个环节出了问题,并给出证据。因为我们没有服务和客户端的任何信息,所以请务必给出全面详细的信息。
4. 上面问题排查中每一步的结果。
**只有了解推送的流程和每个环节的功能才能高效地沟通,所以只有写清楚上面四条信息我们才能够提供技术支持。**
### 附录
#### IM-Server 调用推送服务 HTTP 请求说明
使用POST方式内容为JSON格式参数如下
| 参数 | 类型 | 必需 | 描述 |
| ------ | ------ | --- | ------ |
| sender | string | 是 | 发送者ID |
| senderName | string | 是 | 发送者姓名 |
| convType | int | 是 | 会话类型 |
| target | string | 是 | 接收用户ID |
| targetName | string | 是 | 接收用户名称 |
| line | int | 否 | 会话线路缺省为0 |
| serverTime | long | 是 | 消息时间 |
| pushMessageType | int | 是 | 0 普通消息1 voip消息。在支持透传的系统上voip消息用透传 |
| pushType | int | 是 | 推送类型android推送分为小米/华为/魅族等。ios分别为开发和发布。 |
| pushContent | string | 是 | 消息推送内容 |
| pushData | string | 否 | 消息推送数据 |
| unReceivedMsg | int | 是 | 服务器端没有接收下来的消息数(只计算计数消息) |
| mentionedType | int | 否 | 消息提醒类型0没提醒1提醒了当前用户2提醒了所有人 |
| packageName | string | 否 | 应用包名 |
| deviceToken | int | 否 | 设备token |
| isHiddenDetail | bool | 否 | 是否要隐藏推送详情 |
| language | string | 否 | 接收者的手机语言 |
# 野火IM 推送服务
作为野火IM的推送服务的演示支持小米、华为、魅族、OPPO、Vivo、苹果apns和谷歌FCM。并且可以添加更多的推送厂商和自定义推送模式。
## 工作原理
推送功能对于所有IM来说都是非常重要的功能然而手机系统又没有统一的推送服务对接起来难度很大。另外一方面客户有不同对接需求有的要求使用第三方有的要求使用厂商推送有的需要在海外添加谷歌推送有的对推送的格式有不同的要求。
为了满足各种各样的需求提供足够好的灵活性野火IM把推送子系统独立出来客户只要理解了推送子系统运行的原理就能做好各种自定义处理。
![架构图](https://docs.wildfirechat.cn/architecture/wildfire_architecture.png)
> 如果架构图无法查看,可以点击[这里](https://docs.wildfirechat.cn/architecture/wildfire_architecture.png)查看
图中紫色部分为推送子系统,推送子系统的所有源码都是开源的,且可以随意修改。推送子系统的工作流程如下:
1. 应用启动后推送SDK初始化判断采用那种推送服务比如华为手机就用华为推送小米手机就用小米推送或者全部或部分使用第三方推送。如果客户要加其它推送也是在这里加。选定好推送厂商后就初始化对应推送厂商的SDK注册成功后会得到推送token调用IM SDK的setDeviceToken传入推送token和类型。注意类型是可以扩展的而且对IM系统没有任何影响的。
2. SDK被调用setDeviceToken后会把推送token和类型传入到IM服务IM服务为对应手机保存下来以备后用。事实上IM服务不需要理解token和type的含义只需要透传给推送服务即可。
3. IM服务处理消息时发现用户不在线或者下发消息失败则会启动是否要推送的决策比如消息是否需要推送预制消息已经支持自定义消息需要传入push content用户是否全局静音会话是否被静音客户有多少天没有登录超过7天没登录就不推送。达到推送条件后跟把所有推送需要的内容打包发给推送服务。
4. 推送服务接收到IM服务的请求把推送数据放到消费队列中并立即返回IM服务不能被阻塞然后逐步处理推送事件。每个推送事件中都包含了所有需要处理的数据其中包括1步骤中的推送Token和类型然后根据类型来调用对用推送厂商的服务比如华为/小米/苹果/第三方厂商/谷歌/OPPO/Vivo等调用他们的SDK进行推送。
5. 系统厂商或第三方推送厂商利用他们的通道推送到客户端一般有2种形式一种是通知栏不激活应用只弹出通知栏另外一种形式是透传把应用激活并把数据传递到客户端的推送相关代码种应用激活后有一段活跃时间在这个活跃时间连接IM服务接收下来消息并弹出本地通知。
## 通知类型
一般情况下有2种推送一种是本地通知另外一种是远程推送。
1. 本地通知:指应用在后台处于激活状态,当有此用户的新消息时,消息会被收下来,然后本地弹出通知。
2. 远程推送:指应用处于冻结或者杀死状态,当有此用户的新消息时,消息无法被收下来,需要借助推送服务通知到用户。
本地通知和远程推送在手机上的表现很接近,都是应用放到后台,然后有人给此账号发送消息,通知栏弹出通知。实际上处理流程完全不同。本项目处理的是远程推送。***在处理通知问题时,首先要确认的是本地通知还是远程推送***。
## 远程推送的条件
IM服务判断是否需要推送需要做如下判断
1. 检查客户端是否在线,如果在线不推送。
2. 如果客户端不在线超过7天可以配置不推送。
3. 判断消息内容是否有pushContent和pushContent内置消息会默认处理如果都没有不推送。
4. 如果deviceToken不存在不推送。
5. 检查平台,如果不是支持推送的平台,不推送。
6. 判断会话是否被静音,静音且不是@消息不推送。
7. 检查PC在线时是否设置PC在线时静音是的话不推送。
8. 是否全局静音,全局静音时不推送。
9. 是否开启免打扰,在免打扰时间段内不推送。
## 接入推送
接入推送并不是简单得将推送服务跑起来即可,请详细阅读[接入推送流程](./push.md)
## 添加其它推送服务
由前面的介绍可以看出推送子服务是独立于IM服务而且客户端和服务器部分都是开源的而且考虑到了扩展性可以很容易地添加其它推送类型。具体步骤如下
1. 必须理解推送的工作原理,知道流程是:客户端注册推送-》客户端注册推送成功得到deviceToken-》客户端调用设置deviceToken和类型这两个数据被存储到IM服务。当IM服务需要推送时IM服务打包推送信息包括deviceToken和类型请求到推送服务-》推送服务根据类型选择服务商推送数据。
2. 客户端扩展一个新的推送类型。
3. 客户端在应用启动时,添加处理这种推送类型的注册
4. 在注册成功后会得到deviceToken调用IM SDK的setDeviceToken接口传人deviceToken和类型。
5. 推送服务添加对这种类型的处理。
## 接入个推或者极光
我们提供有个推的分支,切换过去,然后按照个推文档申请推送功能。但要注意只有开通厂商推送功能才可以真的做到离线推送。极光推送可以参考个推或者上面添加其他推送服务的说明来添加,注意同样需要开通厂商推送来实现离线推送。
## 使用到的开源代码
1. [TypeBuilder](https://github.com/ikidou/TypeBuilder) 一个用于生成泛型的简易Builder
## LICENSE
UNDER MIT LICENSE. 详情见LICENSE文件