Spring 整合 websocket 设置
Maven 添加 Jar 包
1 2 3 4 5 6 7 8 9 10 11 12
| <dependency> <groupId>org.springframework</groupId> <artifactId>spring-websocket</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-messaging</artifactId> <version>${spring.version}</version> </dependency>
|
Spring xml 配置方式
1 2 3 4 5 6 7 8 9 10 11 12 13
| <websocket:message-broker application-destination-prefix="/app"> <websocket:stomp-endpoint path="/websocket"> <websocket:sockjs /> </websocket:stomp-endpoint> <websocket:simple-broker prefix="/topic"/> <websocket:client-inbound-channel> <websocket:interceptors> <bean class="net.example.projects.web.WebSocketInterceptor"/> </websocket:interceptors> </websocket:client-inbound-channel> </websocket:message-broker>
|
此处启用 stomp
STOMP
中文为: 面向消息的简单文本协议
websocket
定义了两种传输信息类型:文本信息和二进制信息。类型虽然被确定,但是他们的传输体是没有规定的。所以,需要用一种简单的文本传输类型来规定传输内容,它可以作为通讯中的文本传输协议。
STOMP 是基于帧的协议,客户端和服务器使用 STOMP 帧流通讯
一个 STOMP 客户端是一个可以以两种模式运行的用户代理,可能是同时运行两种模式。
- 作为生产者,通过
SEND
框架将消息发送给服务器的某个服务
- 作为消费者,通过
SUBSCRIBE
制定一个目标服务,通过MESSAGE
框架,从服务器接收消息。
基于 websocket 的一层 STOMP 封装,让业务端只需关心数据本身,不需要太过关心文本协议。当然还是需要了解一些 STOMP 协议各个 Frame 的概念和应用场景。
拦截器配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| public class WebSocketInterceptor extends ChannelInterceptorAdapter {
@Override public Message<?> preSend(Message<?> message, MessageChannel channel) { StompHeaderAccessor accessor = MessageHeaderAccessor.getAccessor(message, StompHeaderAccessor.class); if (StompCommand.CONNECT.equals(accessor.getCommand())) { String userId = accessor.getNativeHeader("userId").get(0); String name = userId; Principal principal = () -> name; WebSocketManager.connect(name); accessor.setUser(principal); return message; } else if (StompCommand.DISCONNECT.equals(accessor.getCommand())) { Principal principal = accessor.getUser(); WebSocketManager.disconnect(principal.getName()); } else {
} return message; } }
|
拦截处理连接和断开操作,Principal 设置连接的用户,之后就可以发送消息到指定用户。
常用 Command
- CONNECT
- CONNECTED
- SEND
- SUBSRIBE
- UNSUBSRIBE
- BEGIN
- COMMIT
- ABORT
- ACK
- NACK
- DISCONNECT
消息
服务器可以通过@MessageMapping
方法处理请求
SendToUser("/topic/websocket")
发送消息
需要强调的是 web.xml 中的路径匹配问题 写为/全部匹配的
如果使用路径匹配/wsk/*
spring 中的地址不能写为<websocket:mapping path=”/wsk/echo” 只需要写为 <websocket:mapping path=”/echo”就可以了,不然无法访问,这个是很多人都会遇到的坑.需特别注意
手动管理 WebSocketSession
配置时添加
1 2 3 4 5
| <websocket:transport> <websocket:decorator-factories> <bean class="net.example.web.CustomWebSocketHandlerDecorator"/> </websocket:decorator-factories> </websocket:transport>
|
添加代码
将 WebSocketSession 保存,留作后续处理