学习记录:
消息推送常见的方式:
1.轮询
浏览器以指定的时间间隔向服务器发起http请求,服务器实时返回数据给浏览器。
弊端:
数据在展示的时候,会有延迟。
会给服务器造成很大的压力。
2.长轮询http1.1
浏览器发出异步ajax请求,服务器端接收到请求以后,会阻塞请求知道有数据或者超时才返回。
优点:
相对于断轮询,有一个阻塞的效果。将轮询时间设置长一点,给服务器造成的压力会小一点。
3.SSE Server Send Event
SSE在服务器和客户端之间打开了一个单向的通道。
服务器相应的不再是一次性的数据包,而是text/event-stream类型的数据流信息
服务器有数据变更的时候将数据流式传输给客户端。
4.websocket
是一种基于TCP连接上进行全双工通信的协议。
websocket API
websocket对象创建
let ws = new WebSocket(URL);
URL格式:协议://ip地址/访问路径
协议名称:ws
websocket对象相关事件
事件:
open
message
error
close
事件对应处理程序:
ws.onopen
ws.onmessage
ws.error
ws.close
描述:
建立链接时触发
客户端收到服务端消息时触发
连接关闭时触发
websocket对象提供的方法:
send() 通过websocket对象调用该方法发送数据给服务端
<script>
let ws = new WebSocket("ws://localhost:8000/chat");
ws.onopen = function()
{
//dosomthing
}
ws.onmessage = function(evt)
{
//通过evt.date 可以获取服务器发送的数据
//do somthing
}
ws.onclose = function()
{
//do somthing
}
</script>
服务端 API
Tomcat7.0.5版本开始支持WebSocket,并且实现了Java WebSocket规范
Java WebSocket应用由一系列的EndPoint组成。EndPoint事一个java对象,代表WebSocket链接的一端,对于服务端,我们可以视为处理具体WenSocket消息的接口。
我们可以通过两种方式定义Endpoint
1.第一种事编程式,即javax.websocket.EndPoint并实现其方法。
2.第二种是注解式,定义一个PoJo,并添加@ServerEndPoint相关注解。
EndPoint实例在WebSocket握手时创建,并在客户端与服务端链接过程中有效,最后在链接关闭的时候,在EndPoint接口中明确定义了其生命周期相关的方法,
规范实现者确保生命周期的各个阶段调用的实例的相关方法,生命周期方法如下:
onOpen() @OnOpen 当开启一个新的会话时调用,该方法是客户端与服务端握手成功后调用的方法
onClose() @OnClose 当会话关闭时调用
onError() @OnError 当连接过程异常时调用
服务端如何接受客户端发送的数据呢?
编程式:
通过添加MessageHandler消息处理器来接受消息
注解式
在定义EndPoint时,通过@OnMessage注解指定接受消息的方法。
服务端如何推送数据给客户端呢?
发送消息由RemoteEndPoint完成,其实例由Session维护。发送消息有两种方式发送消息
1.通过session.getBasicRemote 获取同步消息发送的实例,然后调用sendXxx()方法发送消息
2.通过session.getAsyncRemote 获取异步消息发送实例,然后调用sendXxx方法发送消息
@ServerEndpoint("/myWs")
@Component
public class WsServerEndpoint
{
@OnOpen
public void onOpen(Session session) {
System.out.println("连接成功");
}
@OnMessage
public String onMessage(String text)
{
}
@OnClose
public void onClose(Session session)
{
System.out.println("连接关闭");
}
}
websocket 消息格式
客户端--->服务端
{"toName":"张三","message":"你好"}
服务端--->客户端
1.系统消息格式:{"system":true,"fromName":null,"message":["李四","王五"]}
2.推送给某一个用户的消息格式:{"system":false,fromName:"张三","message":"你好"}
spring-boot整合依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
编写添加配置类,扫描添有@ServerEndPoint注解的Bean
@Configuration
@EnableWebSocket
public class WebsocketConfig
{
@Bean
public ServerEndpointExporter serverEndpoint()
{
return new ServerEndpointExporter();
}
}
编写配置类,用于获取HttpSession对象
public class GetHttpSessionConfigurator extends ServerEndpointConfig.Configurator
{
@Override
public void modifyHandshake(ServerEndpointConfig sec, HandshakeRequest request, HandshakeResponse response) {
HttpSession httpsession = (HttpSession)request.getHttpSession();
//将httpSession对象存储到配置对象中
sec.getUserProperties().put(HttpSession.class.getName(),httpsession);
}
}
在@ServerEndpoint注解中引入配置器
@ServerEndpoint(value = "/chat",configurator = GetHttpSessionConfigurator.class)