简介
Webscoket 是一种在 tcp 之上和 http 同级的应用层协议。ws/wss 使用的也是同 http/https 一样的端口。在建立连接前会发送一段 http/https 的握手协议(使用开发者工具会省略这段握手请求)。
加入依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
在springboot应用中使用有两种方法:
-
官网使用的方法
- 实现 Handler,继承 AbstractWebSocketHandler 类并实现对应方法(官网使用的 TextWebSocketHandler 或 BinaryWebSocketHandler 是其子类 效果一样)
@Slf4j @Component public class MyHandler extends AbstractWebSocketHandler { @Override public void afterConnectionEstablished(WebSocketSession session) throws Exception { // socket连接成功后触发 log.info("建立websocket连接"); } @Override protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception { // 客户端发送普通文件信息时触发 log.info("发送文本消息"); // 获得客户端传来的消息 String payload = message.getPayload(); session.sendMessage(new TextMessage("接收成功了!消息是:" + payload)); log.info("服务端接收到消息 " + payload); } @Override protected void handleBinaryMessage(WebSocketSession session, BinaryMessage message) throws Exception { // 客户端发送二进信息是触发 log.info("发送二进制消息"); } @Override public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception { // 异常时触发 log.error("异常处理"); } @Override public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception { // socket连接关闭后触发 log.info("关闭websocket连接"); } }
- 配置 Config,实现 WebSocketConfigurer 接口(该接口只有一个方法
registerWebSocketHandlers
)
@Configuration @EnableWebSocket public class WebSocketConfig implements WebSocketConfigurer { @Autowired private MyHandler myHandler; @Override public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) { // websocket连接地址 ws://localhost:8080/msg // 测试网址:http://coolaf.com/tool/chattest registry.addHandler(myHandler, "/msg").setAllowedOrigins("*"); } }
- 启动应用,使用 http://coolaf.com/tool/chattest 进行测试
-
传统的 tomcat
@ServerEndpoint
方法- 进行配置 将 @ServerEndpoint 接入 spring 管理
@Configuration public class WebSocketNestConfig { /** * 如果想在使用内嵌容器的Spring Boot应用中使用@ServerEndpoint,你需要声明一个单独的ServerEndpointExporter * * <p>该bean将使用底层的WebSocket容器注册任何被@ServerEndpoint注解的beans。 * * @return ServerEndpointExporter */ @Bean public ServerEndpointExporter serverEndpointExporter() { return new ServerEndpointExporter(); }
- 编写 @ServerEndpoint 类,注意接入spring 需要加 @Component
@Component @ServerEndpoint(value = "/msg/{termId}") @Slf4j public class AgentWebSocketServer { /** * 连接建立成功调用的方法 */ @OnOpen public void onOpen(@PathParam("termId") String termId, Session session) { log.debug("有新的终端{}连接加入!", termId); } /** * 连接关闭调用的方法 */ @OnClose public void onClose() { log.debug("离线"); } /** * 收到客户端消息后调用的方法 * * @param message 客户端发送过来的消息 */ @OnMessage public void onMessage(String message, Session session) { log.debug("收到消息:{}", message); } /** * @param session * @param error */ @OnError public void onError(Session session, Throwable error) { log.error("webSocket发生错误"); error.printStackTrace(); } }
- 启动应用,使用 http://coolaf.com/tool/chattest 进行测试
小提示:@EnableWebSocket 与 @EnableScheduling 不进行设置会产生冲突。websocket 需要创建线程,定时任务也需要创建线程,在创建线程的时候发生了冲突,定时任务创建线程没有成功。造成定时任务所需的 TaskScheduler 被注入成 NullBean,我们需要手动注入一遍
@Bean
public TaskScheduler taskScheduler() {
// 注意是Scheduler,不是Executor
ThreadPoolTaskScheduler scheduling = new ThreadPoolTaskScheduler();
scheduling.setPoolSize(10);
scheduling.initialize();
return scheduling;
}