SpringBoot集成WebSocket

1)添加websocket的依赖

xml 复制代码
<dependency>
     <groupId>org.springframework.boot</groupId>
     <artifactId>spring-boot-starter-websocket</artifactId>
</dependency>

2)添加websocket相关的配置

java 复制代码
@Configuration
public class WebsoketConfig {

    /**
     * 这个Bean会自动注册使用@ServerEndpoint注解声明的websocket endpoint
     */
    @Bean
    public ServerEndpointExporter serverEndpointExporter(){
        return new ServerEndpointExporter();
    }

    /**
     * 为了能在这个类中获取到Spring的ApplicationContext,需要把它让Spring来管理
     * */
    @Bean
    public CustomSpringConfigurator customSpringConfigurator() {
        return new CustomSpringConfigurator();
    }
}

3)添加websocket的业务处理类

java 复制代码
/**
 * 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<>();
    @OnOpen
    public void onOpen(Session session, @PathParam("clientId")String clientId){
        log.info("客户端:{}建立连接", clientId);
        sessionMap.put(clientId, session);
    }
    @OnMessage
    public void onMessage(String msg, @PathParam("clientId")String clientId){
        log.info("收到客户端:{}的消息:{}", msg, clientId);
    }
    @OnClose
    public 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实例。

java 复制代码
public class CustomSpringConfigurator extends ServerEndpointConfig.Configurator implements ApplicationContextAware {

    /**
     * Spring application context.
     */
    private static volatile ApplicationContext applicationContext;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        CustomSpringConfigurator.applicationContext = applicationContext;
    }

    /**
     * Endpoint的实例从Spring的IOC容器去获取,否则tomcat会自己new一个WebsocketServer的实例出来
     * */
    @Override
    public <T> T getEndpointInstance(Class<T> clazz) throws InstantiationException {
        return applicationContext.getBean(clazz);
    }
}

完整的源码下载:https://github.com/xjs1919/enumdemo下面的[websocket-demo](https://github.com/xjs1919/enumdemo/tree/master/websocket-demo)。
参考文档

相关推荐
十年Java程序媛41 分钟前
SpringBoot3 + JDK17 实战复盘:HikariCP 连接耗尽,虚拟线程场景额外注意事项
java·spring boot
2601_962181962 小时前
Spring boot从0到1 - day01
java·spring boot·后端
码视野2 小时前
基于 Spring Boot + Vue3 的【智慧公厕微负压排风除臭与客流人感空间占用导引中台】设计与实现(含PRD/三端高保真源码/大屏)
前端·vue.js·人工智能·spring boot·后端
2601_962062942 小时前
Spring Boot入门——Spring Boot项目的创建
java·数据库·spring boot
ERD Online2 小时前
Cursor 连上 MCP:读一张 ER 图,提交一版建议
数据库·后端·开源·cursor·mcp
思考着亮2 小时前
4.依赖注入_Depends用法_四大应用场景_Yield生成器原理.
后端
思考着亮2 小时前
3.全局中间件_洋葱模型执行机制_跨域CORS配置
后端
思考着亮3 小时前
5.数据库ORM_连接池_自动事务_增删改查高级语法与字典解包
后端
叫我:松哥3 小时前
基于flask仿小米商城管理系统,使用flask开的一个商场网站
数据库·后端·python·flask
Wang's Blog3 小时前
Vibe Coding一人即团队系列35: 基于Claude Code的Spring Boot项目初始化实践
java·spring boot·后端