什么是消息推送(push)

推送的场景比较多,比如有人关注我的公众号,这时我就会收到一条推送消息,以此来吸引我点击打开应用。

消息推送(push)通常是指网站的运营工作等人员,通过某种工具对用户当前网页或移动设备APP进行的主动消息推送。

消息推送一般又分为web端消息推送和移动端消息推送。

消息推送常见方式

短轮询

浏览器以指定的时间间隔向服务器发出HTTP请求,服务器实时返回数据给浏览器

img点击并拖拽以移动

长轮询

浏览器浏览器发出ajax请求,服务器端接收到请求,会阻塞请求直到有数据或者超时才返回

img点击并拖拽以移动

SSE(服务发送事件)

  • SSE在服务器和客户端之间打开一个单向通道
  • 服务器响应的不再是一次性的数据包,而是text/event-stream类型的数据流消息
  • 服务器有数据变更时将数据流式传输客户端

img点击并拖拽以移动

websocket

websocket是一种在基于TCP连接上进行全双工通信的协议

img点击并拖拽以移动

全双工:允许数据在两个方向上同时传输。

半双工:允许数据在两个方向上传输,但是同一个时间段内只允许一个方向传输

WebSocket

WebSocket介绍

Websocket是一种网络通信协议。RFC6455定义它的通信标准。

WebSocket是一种HTML5开始提供的一种在单个TCP连接上进行全双工通讯的协议

HTTP协议是一种无状态的、无连接的、单向的应用层协议。它采取了请求/响应模型。通信请求只能由客户端发起,服务端对请求做出应答处理。

这种通信模型有一个弊端:HTTP协议无法实现服务器主动向客户端发起消息。

这种单向请求的特点,注定如果服务器有连续的状态变化,客户端要获知就非常麻烦。大多数Web应用程序将通过频繁的异步AJAX请求实现长轮询。轮询的效率低,非常浪费资源(因为必须不停的连接,或者HTTP连接始终打开)

http协议与webSocket区别:

http协议:

img点击并拖拽以移动

websocket协议:

img点击并拖拽以移动

webSocket协议

本协议有两部分:握手和数据传输。

握手是基于http协议的。

来自客户端的握手看起来像如下形式:

img点击并拖拽以移动

来自服务器的握手看起来像如下形式(响应):

img点击并拖拽以移动

响应行为101说明建立连接成功

字段说明:

img点击并拖拽以移动

客户端(浏览器)实现

websocket对象

实现webSockets的Web浏览器将通过WebSocketu对象公开所有必须的客户端功能(主要指支持Html5的浏览器)。

以下API用于创建WebSocket对象:

var ws = new WebSocket(url);

参数url格式说明: ws://ip地址:端口号/资源名称

websocket事件

webSocket对象的相关事件

img点击并拖拽以移动

WebSocket方法

WebSocket对象的相关方法:

img点击并拖拽以移动

服务端实现

Tomcat的7.0.5版本开始支持WebSocket,并且实现了JavaWebket规范(JSR356)

Java WebSocket应用由一系列的websocketEndpoint组成。Endpoint是一个java对象,代表WebSocket链接的一端,对于服务端,我们可以通过两种方式定义Endpoint:

  • 第一种是编程式,即继承类javax.websocket.Endpoint并实现其方法。
  • 第二种是注解式,即定义一个POJO,并添加@ServerEndpoint相关注解

Endpoint实例在WebSocket握手时创建,并在客户端与服务端链接关闭时结束。在Endpoint接口中明确定义了与其生命周期相关的方法,规范实现者确保生命周期的各个阶段调用实例相关的方法。生命周期如下:

img点击并拖拽以移动

服务端如何接收客户端发送的数据呢?

通过Session添加MessageHandler消息处理器来接收消息,当采用注解方式定义Endpoint时,我们可以通过@onMessage注解指定接收消息的方法

服务器端如何推送数据给客户端呢?

发送消息则由RemoteEndpoint完成,其实例由Session维护,使用情况,我们可以通过Session.getBasicRemote获取同步消息发送的实例,然后调用其sendXxx()方法就可以发送消息,可以通过Session.getAsyncRemote获取异步消息发送实例。