Spring WebSocket
最近想做个在线网页聊天,第一时间想到的就是WebSocket,之前也没有在SpringBoot中使用过,这次看看文档,大概学习一下,涉及到部分源码。
首先惯例,官方文档地址,websocket和mvc同属于spring web包下,websocket可以脱离mvc单独使用,不过现在开发mvc基本必不可少。
新建SpringBoot工程,引入WebSocket的starter依赖。
上手使用是非常简单的,核心是以下几个类。
WebSocketHandler接口
相当于普通HTTP请求的Controller,主要有建立连接、收到消息、连接断开等方法,和浏览器WebSocket的onopen、onmessage、onclose相对应。
public interface WebSocketHandler {
void afterConnectionEstablished(WebSocketSession session) throws Exception;
void handleMessage(WebSocketSession session, WebSocketMessage<?> message) throws Exception;
...
}
Spring为我们提供了默认实现如BinaryWebSocketHandler、TextWebSocketHandler,见名知意,源码也比较简单。
WebSocketConfigurer接口
类似于WebMvcConfigurer接口,对Handler、拦截器、请求头等进行配置,只有一个方法。
public interface WebSocketConfigurer {
/**
* Register {@link WebSocketHandler WebSocketHandlers} including SockJS fallback options if desired.
*/
void registerWebSocketHandlers(WebSocketHandlerRegistry registry);
}
将Handler注册到Registry中,之后会从Registry添加到WebSocketHandlerMappping中的handleMap中,就进入到了Spring中请求的处理流程中了。
下面两点需要注意
- Handler虽然和Controller很像,但是后者通过RequestMapping注解完成映射,WebSocket模块没有提供类似注解,需要手动在Configurer中注册,个人觉得可能提供注解方式更方便使用。
- 不同于WebMVC,需要手动使用@EnabledWebSocket注解,该注解向容器中注入了HandlerMapping、收集所有的WebSocketConfigurer并调用registry方法,没有这个注解,WebSocket请求不会匹配到HandlerMapping。
配置连接属性
@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer {
@Bean
public ServletServerContainerFactoryBean createWebSocketContainer() {
ServletServerContainerFactoryBean container = new ServletServerContainerFactoryBean();
container.setMaxTextMessageBufferSize(8192);
container.setMaxBinaryMessageBufferSize(8192);
return container;
}
}
总结
- EnableWebSocket
- DelegatingWebSocketConfiguration
- 注入WebSocketHandlerMapping
- 扫描所有WebCocketConfigurer,封装WebSocketHandler为HttpRequestWebSocketHandler添加到HandlerMapping的handleMap中。
- WebSocket请求经过WebSocketHandlerMapping被匹配到,返回封装过的HttpRequestHWebSocketHandler,继续被HttpReuqetsHandlerAdapter匹配,最后调用handle方法,到我们自己写的wsHandler中。
Q.E.D.