1.消息推送常见方式
- 轮询
- 长轮询
- SSE
- websocket
1.1. 轮询方式
- 轮询:浏览器以指定的时间间隔向服务器发出HTTP请求,服务器实时返回数据给浏览器
- 长轮询:浏览器发出HTTP请求,服务器端接收到请求后,会阻塞请求直到有数据或者超时才返回

1.2.SSE(server-sent event):服务器发送事件
SSE在服务器和客户端之间打开一个单向通道- 服务端响应的不再是一次性的数据包,而是
text/event-stream类型的数据流信息 - 服务器有数据变更时将数据流式传输到客户端

1.3.websocket介绍
WebSocket是一种在基于TCP连接上进行全双工通信的协议
问:HTTP是单工的还是双工的还是半双工的?
原理解析

客户端发起http请求,请求升级为websocket协议,服务器响应并切换为websocket协议,响应状态码为101,后续都是通过websocket 进行通信
1.4.客户端【浏览器】API
websocket对象创建
let ws = new WebSocket(URL);
websocket对象相关事件
| 事件 | 事件处理程序 | 描述 |
|---|---|---|
| open | ws.onopen | 连接建立时触发 |
| message | ws.onmessage | 客户端接收到服务器发送的数据时触发 |
| close | ws.close | 连接关闭时触发 |
websocket对象提供的方法
| 方法名称 | 描述 |
|---|---|
| send() | 通过websocket对象调用该方法发送数据给服务端 |
例子如下:
<script>
let ws new WebSocket("ws://localhost/chat");
ws.onopen function(){
};
ws.onmessage function(evt){
//通过evt.data可以获取服务器发送的数据
};
ws.onclose function(){
};
</script>
1.5.服务端 API
Tomcat的7.0.5 版本开始支持WebSocket,并且实现了Java WebSocket规范。
Java WebSocket应用由一系列的Endpoint组成。Endpoint 是一个java对象,代表WebSocket链接的一端,对于服务端,我们可以视为处理具体WebSocket消息的接口。
我们可以通过两种方式定义Endpoint:
第一种是编程式, 即继承类 javax.websocket.Endpoint并实现其方法。
第二种是注解式, 即定义一个POJO, 并添加 @ServerEndpoint相关注解。(一般都是用第二种)
Endpoint实例在WebSocket握手时创建,并在客户端与服务端链接过程中有效,最后在链接关闭时结束。在Endpoint接口中明确定义了与其生命周期相关的方法, 规范实现者确保生命周期的各个阶段调用实例的相关方法。生命周期方法如下:
| 方法 | 描述 | 注解 |
|---|---|---|
| onOpen() | 当开启一个新的会话时调用,该方法是客户端与服务端握手成功后调用的方法 | @OnOpen |
| onClose() | 当会话关闭时调用 | @OnClose |
| onError() | 当连接过程异常时调用 | @OnError |
服务端如何接收客户端发送的数据呢?
- 编程式
通过添加MessageHandler消息处理器来接收消息 - 注解式
在定义Endpoint时,通过@OnMessage注解指定接收消息的方法
服务端如何推送数据给客户端呢?
发送消息则由 RemoteEndpoint 完成, 其实例由 Session 维护。
发送消息有2种方式发送消息
- 通过
session.getBasicRemote获取同步消息发送的实例 , 然后调用其sendXxx()方法发送消息 - 通过
session.getAsyncRemote获取异步消息发送的实例,然后调用其sendXxx()方法发送消息











