springboot集成websocket,服务端心跳检测

@Component
@EnableScheduling
@Slf4j
public class WebSocketHeartBeatTask {

    /**
     * 每10秒进行一次websocket心跳检测
     */
    @Scheduled(cron = "0/10 * * * * ?")
    public void beatTask() {
        AtomicInteger num = new AtomicInteger();
        SessionMgr.nativeSessions.values().stream().parallel().forEach(session->{
            try {
                session.sendMessage(new PingMessage());
                num.getAndIncrement();
            } catch (Exception e) {
                log.error("websocket心跳异常",e);
            }
        });
        log.info("websocket心跳检测结果,共【{}】个连接", num);
    }
}

<think>我们正在讨论如何在Spring Boot中实现WebSocket服务端。根据引用内容,我们可以总结出以下步骤: 1. 添加依赖:在pom.xml中添加spring-boot-starter-websocket依赖。 2. 创建WebSocket配置类:使用@Configuration和@EnableWebSocket注解,实现WebSocketConfigurer接口,并注册WebSocket处理器和设置端点。 3. 创建WebSocket处理器:可以继承TextWebSocketHandler类,并重写相关方法(如处理文本消息、连接建立、连接关闭等)。 4. 在处理器中处理消息:例如,使用@MessageMapping注解(如果使用STOMP)或者直接处理WebSocket消息。 5. 使用SimpMessagingTemplate(如果使用STOMP)来向客户端发送消息。 但是,注意引用[3]中展示的是不使用STOMP的简单WebSocket配置。而引用[2]提到使用@MessageMapping和SimpMessagingTemplate,这是STOMP子协议的方式。 因此,我们需要区分两种方式: 方式一:使用低级别的WebSocket API(不涉及STOMP) 方式二:使用STOMP over WebSocket(更高级,支持注解和消息代理) 用户问题没有明确要求使用哪种,所以我们可以分别介绍两种方式的基本步骤。 由于引用[1][3][4][5]都是关于服务端实现的,我们结合这些引用给出两种方式的步骤。 下面我们分别介绍两种实现方式。</think>### Java Spring Boot WebSocket 服务端实现步骤 以下是基于引用内容的完整实现流程(包含两种模式:原生WebSocket和STOMP协议): --- #### 一、添加依赖(必需) 在`pom.xml`中添加WebSocket支持: ```xml <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-websocket</artifactId> </dependency> ``` [^1] --- #### 二、配置WebSocket端点(两种模式) ##### 模式1:原生WebSocket API(简单场景) ```java @Configuration @EnableWebSocket public class WebSocketConfig implements WebSocketConfigurer { @Override public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) { registry.addHandler(myHandler(), "/ws") // 端点路径 .setAllowedOrigins("*"); // 允许跨域 } @Bean public WebSocketHandler myHandler() { return new TextWebSocketHandler() { @Override protected void handleTextMessage(WebSocketSession session, TextMessage message) { // 处理客户端消息 String payload = message.getPayload(); session.sendMessage(new TextMessage("ECHO: " + payload)); } }; } } ``` [^3] ##### 模式2:STOMP协议(高级功能) ```java @Configuration @EnableWebSocketMessageBroker public class StompConfig implements WebSocketMessageBrokerConfigurer { @Override public void registerStompEndpoints(StompEndpointRegistry registry) { registry.addEndpoint("/stomp") // STOMP端点 .setAllowedOrigins("*") .withSockJS(); // 支持SockJS } @Override public void configureMessageBroker(MessageBrokerRegistry config) { config.enableSimpleBroker("/topic"); // 消息代理前缀 config.setApplicationDestinationPrefixes("/app"); // 应用前缀 } } ``` [^2] --- #### 三、实现消息处理器 ##### 原生WebSocket处理器 ```java public class MyHandler extends TextWebSocketHandler { @Override public void afterConnectionEstablished(WebSocketSession session) { // 连接建立时执行(可存储session) } @Override protected void handleTextMessage(WebSocketSession session, TextMessage message) { // 处理文本消息 String payload = message.getPayload(); if (payload.contains("AUTH")) { // 认证逻辑(结合HttpSession) HttpHeaders headers = session.getHandshakeHeaders(); String token = headers.getFirst("Authorization"); // 验证token并关联用户信息[^4] } session.sendMessage(new TextMessage("Processed: " + payload)); } } ``` ##### STOMP消息控制器 ```java @Controller public class StompController { @Autowired private SimpMessagingTemplate messagingTemplate; // 处理客户端发送到/app/chat的消息 @MessageMapping("/chat") public void handleChat(ChatMessage message) { // 广播到所有订阅/topic/messages的客户端 messagingTemplate.convertAndSend("/topic/messages", "[" + message.getUser() + "]: " + message.getContent()); } } ``` [^2] --- #### 四、获取用户信息(结合HTTP会话) ```java @Controller public class AuthController { // 在握手时拦截器获取用户信息 @Bean public HandshakeInterceptor authInterceptor() { return new HandshakeInterceptor() { @Override public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Map<String, Object> attributes) { // 从HTTP请求获取用户信息 ServletServerHttpRequest req = (ServletServerHttpRequest) request; HttpSession session = req.getServletRequest().getSession(); attributes.put("user", session.getAttribute("user")); return true; } }; } } ``` 在配置中添加拦截器: ```java registry.addHandler(myHandler(), "/ws") .addInterceptors(authInterceptor()); // 添加拦截器[^4] ``` --- #### 五、测试服务端 使用Java客户端测试连接: ```java public class WebSocketTest { public static void main(String[] args) throws Exception { WebSocketClient client = new StandardWebSocketClient(); WebSocketSession session = client.doHandshake( new TextWebSocketHandler() { @Override public void handleMessage(WebSocketSession session, WebSocketMessage<?> message) { System.out.println("Received: " + message.getPayload()); } }, "ws://localhost:8080/ws" // 服务端地址 ).get(); session.sendMessage(new TextMessage("Hello Server!")); } } ``` [^5] --- ### 关键配置对比 | **功能** | **原生WebSocket** | **STOMP协议** | |------------------|---------------------------------------|----------------------------------------| | **协议支持** | 基础WebSocket | WebSocket + STOMP消息格式 | | **消息路由** | 需手动处理 | 支持@MessageMapping自动路由 | | **广播机制** | 需维护session列表 | 内置SimpleBroker广播 | | **认证集成** | 通过拦截器获取HttpSession | 支持STOMP认证头 | | **适用场景** | 简单消息交换 | 复杂消息系统(订阅/发布) | --- ### 常见问题解决方案 1. **跨域问题** 在配置中使用`.setAllowedOrigins("*")`[^3] 2. **获取用户信息** 通过`HandshakeInterceptor`拦截HTTP会话[^4] 3. **心跳保活** 配置`@EnableWebSocketMessageBroker`时设置心跳: ```java config.setHeartbeatValue(new long[]{10000, 20000}); // 心跳间隔(ms) ``` ---
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值