前言
最近工作需要用到 Websocket 协议。好奇来自 Jdk 包的 @ServerEndpoint
是如何与 Spring Boot
集成的,特此记录一下结论。
表象
如果要暴露形如 ws://${ip}:${port}/ws
的服务地址,用于websocket 通信,需要完成以下步骤:
@Component
必须与@ServerEndpoint
搭配使用@OnXX
类的注解同样来自javax.websocket.*
import javax.websocket.*;
import javax.websocket.server.ServerEndpoint;
import java.util.concurrent.atomic.AtomicInteger;
@Component
@ServerEndpoint(value = "/ws")
public class MyWsEndpoint {
@OnOpen
public void onOpen(Session session) {
}
@OnClose
public void onClose(Session session, CloseReason closeReason) {
}
@OnMessage
public void onMessage(String text, Session session) {
}
@OnError
public void onError(Session session, Throwable throwable) {
}
}
- 将
ServerEndpointExporter
以@Bean
的形式告知 Spring
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;
@Configuration
public class MyWsConfig {
@Bean
public ServerEndpointExporter serverEndpointExporter() {
return new ServerEndpointExporter();
}
}
理解
以上步骤留有疑问
- 为啥要用
@Component
注解 ServerEndpointExporter
有什么用
解答:
context.getBeanNamesForAnnotation(ServerEndpoint.class);
以上代码很直观了
- 要求被暴露的websocket服务类必须是个bean,所以要有
@Component
注解 - ServerEndpointExporter 的作用是将所有
@ServerEndpoint
的bean 注册进容器里
后记
@ServerEndpoint
能够方便的与 Spring 集成。简单的业务开发上已经够用了- 在对协议交互中(如握手阶段)加入更多业务逻辑,可以再考虑使用 Spring 自身的 websocket 支持。