SpringBoot集成WebSocket
1)添加websocket的依赖
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
2)添加websocket相关的配置
@Configuration
public class WebsoketConfig {/*** 这个Bean会自动注册使用@ServerEndpoint注解声明的websocket endpoint*/@Beanpublic ServerEndpointExporter serverEndpointExporter(){return new ServerEndpointExporter();}/*** 为了能在这个类中获取到Spring的ApplicationContext,需要把它让Spring来管理* */@Beanpublic CustomSpringConfigurator customSpringConfigurator() {return new CustomSpringConfigurator();}
}
3)添加websocket的业务处理类
/*** websocket服务端处理程序* configurator属性可以从Spring容器中去获取Endpoint对象实例* */
@Slf4j
@Component
@ServerEndpoint(value = "/ws/{clientId}", configurator = CustomSpringConfigurator.class)
public class WebsocketServer {/*** 保存clientId和session的对应关系* */private Map<String, Session> sessionMap = new ConcurrentHashMap<>();@OnOpenpublic void onOpen(Session session, @PathParam("clientId")String clientId){log.info("客户端:{}建立连接", clientId);sessionMap.put(clientId, session);}@OnMessagepublic void onMessage(String msg, @PathParam("clientId")String clientId){log.info("收到客户端:{}的消息:{}", msg, clientId);}@OnClosepublic void onClose(@PathParam("clientId")String clientId){log.info("客户端:{}断开连接", clientId);sessionMap.remove(clientId);}/*** 主动向client推送消息* */public void sendToClient(String clientId, String message) throws Exception{Session session = sessionMap.get(clientId);if(session == null){log.error("客户端:{}不在线", clientId);}else{session.getBasicRemote().sendText(message);}}
}
注意这里的configurator属性设置的CustomSpringConfigurator,这个configurator的作用是让tomcat从SpringIOC容器中去获取Endpoint的实例,否则的话,就会出现SpringIOC中有一个Endpoint实例,tomcat还会自己去new一个Endpoint实例,此时在OnOpen、OnMessage、OnClose中无法使用SpringIOC注入属性成员。
public class CustomSpringConfigurator extends ServerEndpointConfig.Configurator implements ApplicationContextAware {/*** Spring application context.*/private static volatile ApplicationContext applicationContext;@Overridepublic void setApplicationContext(ApplicationContext applicationContext) throws BeansException {CustomSpringConfigurator.applicationContext = applicationContext;}/*** Endpoint的实例从Spring的IOC容器去获取,否则tomcat会自己new一个WebsocketServer的实例出来* */@Overridepublic <T> T getEndpointInstance(Class<T> clazz) throws InstantiationException {return applicationContext.getBean(clazz);}
}
完整的源码下载:https://github.com/xjs1919/enumdemo下面的websocket-demo。
参考文档