Spring WebSocket 像写http接口一样处理WebSocket消息(Stomp协议)

时间:2025-03-18 09:07:17

简单的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