Spring WebSocket 像写http接口一样处理WebSocket消息(Stomp协议)
简单的WebSocket服务搭建
在聊Stomp协议之前,先看一下Spring boot使用比较原始的方法是怎么搭建WebSocket服务的
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
@ServerEndpoint("/ws")
public class WebSocketTest {
/**
* 客户端和服务器建立连接后执行
* @param session
*/
@OnOpen
public void onOpen(Session session) {
}
/**
* 客户端和服务器断开连接后执行
* @param session
*/
@OnClose
public void onClose(Session session) {
}
/**
* 接收到客户端发送的消息时
* @param message
* @param session
*/
@OnMessage
public void onMessage(String message, Session session) {
//所有的消息都发送到这里,需要自己实现消息路由,将不同类型的消息转发到对应的模块处理
}
}
传统方法代码很简单,如果没有复杂的业务逻辑,直接这样使用,在onMessage中处理业务逻辑完全没问题,但是如果消息种类多,业务复杂,那就需要自定义消息协议,实现对不同种类消息的处理
基于Stomp协议的WebSocket服务
如果不想自定义消息协议,怎么办?还好Spring WebSocket提供了对Stomp协议的支持,先上代码
/**
*
* WebSocket配置示例
*
*/
@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
@Autowired
private WebSocketChannelInterceptor channelInterceptor;
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry
//连接地址(比如ws://127.0.0.1:8080/ws)
.addEndpoint("/ws")
//允许跨域
.setAllowedOriginPatterns("*")
//提高兼容性,某些老版本浏览器不支持WebSocket,则可以使用SockJS库实现,如果服务启用 SockJS,在使用Postman之类的工具建立连接时,需要在服务路径后加上/websocket
.withSockJS();
}
@Override
public void configureMessageBroker(MessageBrokerRegistry registry) {
//发送消息路径的前缀
registry.setApplicationDestinationPrefixes("/app");
}
@Override
public void configureClientInboundChannel(ChannelRegistration registration) {
//自定义的消息拦截器,用于鉴权等操作,如果不需要自定义拦截器,configureClientInboundChannel函数可以删掉
registration.interceptors(channelInterceptor);
}
}
/**
* WebSocket消息处理,类似于Spring MVC中普通http接口的写法,只是注解从@RequestMapping换成了@MessageMapping
*
* @author longmap
*
*/
@Component
@RestController
@MessageMapping("/msg/test")
public class MsgTestController {
/**
* 接收消息
* @param protocolText 消息内容(Spring已经解析过Stomp协议了,这里收到的就是有效内容)
*/
@MessageMapping("/1")
public void test1(String protocolText) {
System.out.println(protocolText);
}
}
只需要上面两段代码,就可以实现不同类型的消息发送到指定路径下处理,就和普通http接口一样
Stomp消息内容示例:
SEND
sendHeader:222222222
destination:/app/msg/test/1
content-length:8
这是一条消息fgfsgfg