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;
    }

}

总结

  1. EnableWebSocket
  2. DelegatingWebSocketConfiguration
    1. 注入WebSocketHandlerMapping
    2. 扫描所有WebCocketConfigurer,封装WebSocketHandler为HttpRequestWebSocketHandler添加到HandlerMapping的handleMap中。
  3. WebSocket请求经过WebSocketHandlerMapping被匹配到,返回封装过的HttpRequestHWebSocketHandler,继续被HttpReuqetsHandlerAdapter匹配,最后调用handle方法,到我们自己写的wsHandler中。

Q.E.D.


一切很好,不缺烦恼。