服务器与客户端消息推送的原理
其实服务端与客户端实现消息推送的方式有几种:
1、客户端不断的查询服务器,检查新的内容,也就是所谓的pull或者轮询的方式;
2、客户端与服务器之间维持一个TCP/IP长连接(在HTTP1.1中,所有的请求都认为是长连接),服务器向客户端push;
3、当服务端有新内容的时候,发送一条类似短信的信令给客户端,客户端收到货从服务器下载新内容,也就是SMS的推送方式;
对于第一种方式有以下的缺点:
1、因为需要不断地轮询,所以手机会很耗电;
2、容易被系统杀死;
对于第二种方式:
我们首先来了解一下HTTP长连接的相关知识:
在HTTP1.1中,所有的链接都认为是长连接;HTTP长连接是一个在TCP连接的基础上,发送多个HTTP请求以及接收多个HTTP响应,这是为了避免每一次请求都去打开一个新的连接
在这里的消息推送系统中,HTTP长连接的作用就是向服务器发送请求,然后一直等待服务器的返回数据;这就相当于客户端在“监听”服务器,可以随时收到来自服务器的消息。
在这里还涉及到了同步与异步、阻塞与非阻塞等相关知识:
同步:IO操作将导致请求进程阻塞,知道IO操作完成,也就是说客户端在发送请求之后,必须得在服务端有回应之后才发送下一个请求;
异步:IO操作不导致请求进程阻塞,也就是说客户端在发送请求之后,不必等待服务端的回应就可以发送下一个请求;
阻塞:服务端的线程或者进程没有处理完数据的时候,不会返回,线程或者进程会被挂起,不再相应其他请求;
非阻塞:服务器端在没有处理完的时候会立即返回,不会挂起 线程或者进程,可以继续响应其他的请求;
阻塞和非阻塞是服务器端对请求的处理方式,在消息推送系统中,客户端+服务器一起,使用的是异步非阻塞。
1、客户端发出一个http长连接请求,然后等待服务端的响应,这个请求是异步的,所以客户端可以继续其他工作,比如发起其他的ajax请求等等。
2、服务端接到请求之后,并不立即发出数据,而是hold住这个连接,这个处理是非阻塞的,所以服务器还可以处理其他的请求;
3、在某个时刻,服务器有新的数据了,服务器再主动把这个消息推送出去,即通过之前建立的连接将数据推送给客户端;
4、客户端收到返回,这个时候就可以处理数据了,同时再次发起新的长连接。
而对于移动端来说:
首先说android端的:
普通的socket连接对服务器的消耗太大,所以就出现了像MQTT这种轻量级低消耗的协议来维护长连接;android维护长连接需要心跳机制,客户端发送一个心跳给服务器,服务器给客户端一个心跳应答,这样就形成了一次完整的握手,这个握手让双方都知道他们之间的连接没有断开,客户端是在线的。如果超过一个时间的阀值,客户端没有收到服务器的应答或者服务器没有收到客户端的心跳,那么对客户端来说则断开与服务器的连接重新建立一个连接,对服务器来说只要断开这个连接即可。
android的长连接是由每个应用各自维护的,于是每个应用如果在24小时在线,那么都得各自维护一个长连接,这种电量的消耗是可想而知的。
接下来对于IOS的:
IOS长连接是由系统维护的,也就是说苹果的ios系统在系统级别维护了一个客户端与苹果服务器的长连接,ios的所有应用上的推送都是先将消息推送到苹果的服务器,然后苹果的服务器通过这个系统级别的长连接推送到手机端上,这样有几个好处:
1、在手机终端始终只要维护一个长连接即可,而且由于这个长连接是系统级别的,不会出现被杀死而无法推送的情况;
2、省电,不会出现每个应用都各自维护一个自己的长连接;
3、安全,只有在苹果注册的开发者才能进行推送;
在这里解释一下MQTT协议:
轻量级的machine-to-machine通信协议;
publish/subscribe模式(发布订阅模式)
基于tcp/ip
支持Qos
适合于低宽带、不可靠连接、嵌入式设备、cpu内存资源紧张;
是一种比较不错的android消息推送方案
FacebookMessager采用了MQTT