Skip to content

WebSocket API

在响应式栈中查看等效项

Spring Framework 提供了一个 WebSocket API,你可以使用它来编写处理 WebSocket 消息的客户端和服务器端应用程序。

WebSocketHandler

在响应式栈中查看等效项

创建一个 WebSocket 服务器非常简单,只需实现 WebSocketHandler,或者更常见的是继承 TextWebSocketHandlerBinaryWebSocketHandler。以下示例使用 TextWebSocketHandler

java
public class MyHandler extends TextWebSocketHandler {

	@Override
	protected void handleTextMessage(WebSocketSession session, TextMessage message) {
		// ...
	}
}
kotlin
class MyHandler : TextWebSocketHandler() {

	override fun handleTextMessage(session: WebSocketSession, message: TextMessage) {
		// ...
	}
}

你可以使用专用的 WebSocket 编程式配置或 XML 命名空间将上述 WebSocket 处理程序映射到特定的 URL:

java
@Configuration
@EnableWebSocket
public class WebSocketConfiguration implements WebSocketConfigurer {

	@Override
	public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
		registry.addHandler(myHandler(), "/myHandler");
	}

	@Bean
	public WebSocketHandler myHandler() {
		return new MyHandler();
	}
}
kotlin
@Configuration
@EnableWebSocket
class WebSocketConfiguration : WebSocketConfigurer {

	override fun registerWebSocketHandlers(registry: WebSocketHandlerRegistry) {
		registry.addHandler(myHandler(), "/myHandler")
	}

	@Bean
	fun myHandler(): WebSocketHandler {
		return MyHandler()
	}
}
xml
<websocket:handlers>
    <websocket:mapping path="/myHandler" handler="myHandler"/>
</websocket:handlers>

<bean id="myHandler" class="org.springframework.docs.web.websocket.MyHandler"/>

WebSocket 握手

自定义初始 HTTP WebSocket 握手请求的最简单方法是通过 HandshakeInterceptor。你可以使用这种拦截器来阻止握手或使任何属性对 WebSocketSession 可用。以下示例使用内置拦截器将 HTTP 会话属性传递给 WebSocket 会话:

java
@Override
public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
    registry.addHandler(new MyHandler(), "/myHandler")
            .addInterceptors(new HttpSessionHandshakeInterceptor());
}
kotlin
override fun registerWebSocketHandlers(registry: WebSocketHandlerRegistry) {
    registry.addHandler(MyHandler(), "/myHandler")
        .addInterceptors(HttpSessionHandshakeInterceptor())
}

部署与服务器配置

服务器配置

你可以配置底层 WebSocket 服务器的属性,例如输入消息缓冲大小、空闲超时等。

对于 Jakarta WebSocket 服务器,可以添加 ServletServerContainerFactoryBean

java
@Bean
public ServletServerContainerFactoryBean createWebSocketContainer() {
    ServletServerContainerFactoryBean container = new ServletServerContainerFactoryBean();
    container.setMaxTextMessageBufferSize(8192);
    container.setMaxBinaryMessageBufferSize(8192);
    return container;
}
kotlin
@Bean
fun createWebSocketContainer() = ServletServerContainerFactoryBean().apply {
    maxTextMessageBufferSize = 8192
    maxBinaryMessageBufferSize = 8192
}

允许的来源 (Allowed Origins)

默认情况下,WebSocket 和 SockJS 仅接受同源请求。你可以允许所有来源或指定的列表:

java
registry.addHandler(myHandler(), "/myHandler").setAllowedOrigins("https://mydomain.com");
kotlin
registry.addHandler(myHandler(), "/myHandler").setAllowedOrigins("https://mydomain.com")

补充教学

1. 生命周期方法

WebSocketHandler 中,除了处理消息,你还可以重写:

  • afterConnectionEstablished: 连接建立后调用,通常用于存储 Session。
  • afterConnectionClosed: 连接关闭后调用,用于清理资源。

2. 线程安全问题

基础的 WebSocket Session 不是线程安全的。如果你需要从多个线程并发发送消息,请使用 ConcurrentWebSocketSessionDecorator 包装原始 Session。

3. 处理二进制数据

如果你的应用需要处理图片或文件流,请继承 BinaryWebSocketHandler 并重写 handleBinaryMessage 方法。

Based on Spring Framework.