WebSocket
WebSocket是一种在基于TCP连接上进行全双工通信的协议
全双工(Full Duplex):允许数据在两个方向上同时传输。
半双工(Half Duplex):允许数据在两个方向上传输,但是同一个时间段内只允许一个方向上传输。
原理
请求数据
1 | GET ws://localhost/chat |
响应数据
1 | 101 Switching Protocols |
WebSocket API
前端
对象创建
1 | let ws = new WebSocket(URL); |
- 格式:协议://ip地址/访问路径
- 协议:协议名称为 ws
相关事件
事件 | 事件处理程序 | 描述 |
---|---|---|
open | ws.onopen |
连接建立时触发 |
message | ws.onmessage |
客户端接收到服务器发送的数据时触发 |
close | ws.onclose |
连接关闭时触发 |
对象提供的方法
方法名称 | 描述 |
---|---|
send() | 通过websocket对象调用该方法发送数据给服务端 |
示例
1 | <script> |
后端
Tomcat的7.0.5 版本开始支持WebSocket,并且实现了Java WebSocket规范。
Endpoint
Java WebSocket应用由一系列的Endpoint组成。
Endpoint 是一个java对象,代表WebSocket链接的一端,对于服务端,我们可以视为处理具体WebSocket消息的接口。
我们可以通过两种方式定义Endpoint:
- 编程式:即继承类 javax.websocket.Endpoint并实现其方法。
- 注解式:即定义一个POJO, 并添加
@ServerEndpoin
t相关注解。
Endpoint实例在WebSocket握手时创建,并在客户端与服务端链接过程中有效,最后在链接关闭时结束。在Endpoint接口中明确定义了与其生命周期相关的方法, 规范实现者确保生命周期的各个阶段调用实例的相关方法。生命周期方法如下:
方法 | 描述 | 注解 |
---|---|---|
onOpen() |
当开启一个新的会话时调用,该方法是客户端与服务端握手成功后调用的方法 | @OnOpen |
onClose() |
当会话关闭时调用 | @OnClose |
onError() |
当连接过程异常时调用 | @OnError |
接收数据
编程式
通过添加 MessageHandler 消息处理器来接收消息
注解式
在定义Endpoint时,通过@OnMessage注解指定接收消息的方法
发送数据
发送消息则由 RemoteEndpoint 完成, 其实例由 Session 维护。
发送消息有2种方式发送消息
通过session.getBasicRemote 获取同步消息发送的实例 , 然后调用其 sendXxx()方法发送消息
通过session.getAsyncRemote 获取异步消息发送实例,然后调用其 sendXxx() 方法发送消息
getBasicRemote()
getBasicRemote()
方法是同步的,消息发送是阻塞的。这意味着当调用这个方法发送消息时,会等待消息完全发送出去后才会继续执行后续代码。- 这个方法适合于需要确保消息按照发送顺序同步到客户端的场景,例如需要按顺序发送消息给客户端并等待客户端处理完毕后再发送下一条消息的情况。
getAsyncRemote()
getAsyncRemote()
方法是异步的,消息发送是非阻塞的。这意味着当调用这个方法发送消息时,会立即返回,并且消息的发送过程是在后台进行的,不会阻塞当前线程。- 这个方法适合于需要快速发送消息而不关心发送结果的场景,例如需要发送大量消息给客户端或需要在后台发送消息的情况。
示例
1 | import javax.websocket.OnOpen; |
代码实现
引入起步依赖
1 | <dependency> |
编写配置类,扫描添加有@ServerEndpoint注解的 Bean
1 |
|
@Bean
用于注入ServerEndpointExporter,自动注册使用@ServerEndpoint
注解的类
编写配置类,用于获取 HttpSession 对象
1 | public class GetHttpSessionConfig extends ServerEndpointConfig.Configurator { |
继承ServerEndpoint的内部类,重写了 modifyHandshake
方法,该方法在 WebSocket 握手时被调用,允许我们修改握手过程中的配置信息。
通过 HandshakeRequest
对象获取 HttpSession,并将其存储在 ServerEndpointConfig
的用户属性中,以便在后续的 WebSocket 连接中可以访问 HttpSession。
可以在 @ServerEndpoint 注解中引入配置器
1 |
value参数对应前端创建WebSocket对象所指定的接口
Controller
1 |
|
通过注解继承Endpoint就能用了
1 |
|
- 本文作者: NICK
- 本文链接: https://nicccce.github.io/TechNotes/WebSocket-Note/
- 版权声明: 本博客所有文章除特别声明外,均采用 MIT 许可协议。转载请注明出处!