背景
偶尔我们会遇到这样的情况,手机信号不佳,需要联网的app都无法加载,但是却能突然收到一个消息通知;
应用内尚加载不出需要联网的信息,为何却能收到应用通知?
这要从客户端和服务的交互模式说起;
服务端和客户端的交互
一般而言是“服务端响应式”的:
服务端有固定的ip/域名,可以提供稳定的访问支持;
客户端有需求的时候,主动向服务端发送HTTP请求,等待返回结果;
但是如果服务端需要主动向客户端发送某个请求,这个是有很多问题的:
- 客户端的网络状态是不稳定的;
- 客户端没有固定的ip地址、稳定的响应能力;
- HTTP请求是一个基于请求-响应模型的协议,服务端只能被动等待请求;
服务端主动请求
现有的技术已经实现了服务端和客户端的互通:
like:
- 服务器发送事件(Server-Sent Events,简称SSE):SSE是基于HTTP协议的,它允许服务端向客户端单向发送消息。SSE不需要特殊的协议或服务器实现,但需要在客户端建立持久连接。SSE默认支持断线重连。
- HTTP长轮询(Long Polling):长轮询是一种在客户端与服务器之间建立持久连接的技术,它允许服务器在一定时间内保持连接,并向客户端发送消息。当连接超时或服务器发送消息时,连接将被重新建立。
- HTTP流(HTTP Streaming):HTTP流允许服务器通过响应流持续地向客户端发送数据,客户端可以随时断开连接。与长轮询不同,HTTP流没有等待服务器发送消息的时间限制。
- WebSocket:WebSocket是一种全双工通信协议,允许服务端和客户端之间建立持久连接,实现双向通信。WebSocket需要单独的服务器实现,但可以实现更高效的数据传输。
移动端消息通知
移动端的消息通知,顾名思义,是客户端有消息,需要实时发送通知给客户端;
这里是典型的 Server —> Client的交互场景;
通常的实现方式
- 实现并维护一套服务端和客户端之间的长链接(任选上面的实现方式)
- 如果业务强相关:通常IM的应用是有自己维护的必要的,因为业态本身就是实时性的;
- 如果仅仅是一个需要通知的功能:自己维护这些是有代价的,而且大量的长连接会占用服务资源,虽然有各种诸如链接复用等策略可以在一定程度上节约资源占用,但是仍然是得不偿失的;
- 更通用的实现方式:使用三方服务
- Umeng
- 极光
三方实现的原理
一般的通知大体分了两种通道:
- 长连接(服务本身的机制)
- 厂商通道
- iOS 和 Android 本身都是有一个系统级别的推送,所谓系统级别的推送就是不依赖某一个应用,由服务器直接下方消息至手机本身
- IOS: APNS
- Android: GCM
这里的厂商通道通常的过程就是:
- iOS 和 Android 本身都是有一个系统级别的推送,所谓系统级别的推送就是不依赖某一个应用,由服务器直接下方消息至手机本身
- 安装app期间,将设备信息注册到服务端
- 服务端收到注册信息
- 服务端直接下发消息到手机
all in all,这种不需要走常规路子的方式解释了为什么没有网络的时候偶尔也能收到消息通知;