SpringBoot3整合WebSocket详细指南

 更新时间:2024年12月16日 10:09:14   作者:CoderJia_  
SpringBoot 3 整合 WebSocket 提供了一种高效的实时通信解决方案,通过本文的配置和示例,可以快速实现,感兴趣的哦朋友跟随小编一起看看吧

1. 什么是WebSocket?

WebSocket 是一种网络通信协议,提供全双工通信通道,使服务器可以主动向客户端推送数据。与传统的 HTTP 请求-响应模式不同,WebSocket 在建立连接后,允许服务器和客户端之间进行双向实时通信。

主要特点:

  • 建立在 TCP 协议之上
  • 与 HTTP 协议有良好的兼容性
  • 数据格式轻量,性能开销小
  • 可以发送文本和二进制数据
  • 没有同源限制,客户端可以与任意服务器通信

2. 环境准备

2.1 项目依赖

首先在pom.xml中添加必要的依赖:

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>3.2.5</version>
</parent>
<dependencies>
    <!-- WebSocket依赖 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-websocket</artifactId>
    </dependency>
    <!-- Web依赖 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <!-- Lombok依赖(可选) -->
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <optional>true</optional>
    </dependency>
</dependencies>

image-20241215200948577

3. WebSocket配置

3.1 WebSocket配置类

创建 WebSocket 配置类,启用 WebSocket 功能并注册端点:

package com.coderjia.boot3websocket.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.WebSocketHandler;
import org.springframework.web.socket.config.annotation.EnableWebSocket;
import org.springframework.web.socket.config.annotation.WebSocketConfigurer;
import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry;
/**
 * @author CoderJia
 * @create 2024/12/15 下午 08:11
 * @Description
 **/
@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer {
    @Override
    public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
        registry.addHandler(webSocketHandler(), "/websocket")
                .setAllowedOrigins("*"); // 允许跨域访问
    }
    @Bean
    public WebSocketHandler webSocketHandler() {
        // 使用自定义的WebSocket处理器
        return new CustomWebSocketHandler();
    }
}

3.2 自定义WebSocket处理器

创建自定义的 WebSocket 处理器,处理消息收发:

package com.coderjia.boot3websocket.config;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;
import java.io.IOException;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
 * @author CoderJia
 * @create 2024/12/15 下午 08:21
 * @Description
 **/
@Component
@Slf4j
public class CustomWebSocketHandler extends TextWebSocketHandler {
    // 用于存储WebSocket会话
    private final Map<String, WebSocketSession> sessions = new ConcurrentHashMap<>();
    @Override
    public void afterConnectionEstablished(WebSocketSession session) throws Exception {
        String sessionId = session.getId();
        sessions.put(sessionId, session);
        log.info("WebSocket连接建立成功:{}", sessionId);
    }
    @Override
    protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
        String payload = message.getPayload();
        log.info("收到消息:{}", payload);
        // 发送回复消息
        String replyMessage = "服务器收到消息:" + payload;
        session.sendMessage(new TextMessage(replyMessage));
    }
    @Override
    public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
        String sessionId = session.getId();
        sessions.remove(sessionId);
        log.info("WebSocket连接关闭:{}", sessionId);
    }
    @Override
    public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
        log.error("WebSocket传输错误", exception);
    }
    // 广播消息给所有连接的客户端
    public void broadcastMessage(String message) {
        sessions.values().forEach(session -> {
            try {
                session.sendMessage(new TextMessage(message));
            } catch (IOException e) {
                log.error("广播消息失败", e);
            }
        });
    }
}

4. 控制器

创建 REST 控制器,用于测试消息广播:

@RestController
@RequestMapping("/api/websocket")
public class WebSocketController {
    private final CustomWebSocketHandler webSocketHandler;
    public WebSocketController(CustomWebSocketHandler webSocketHandler) {
        this.webSocketHandler = webSocketHandler;
    }
    @PostMapping("/broadcast")
    public ResponseEntity<String> broadcastMessage(@RequestBody String message) {
        webSocketHandler.broadcastMessage(message);
        return ResponseEntity.ok("消息广播成功");
    }
}

5. 前端实现

5.1 HTML页面

<!DOCTYPE html>
<html lang="en">
<head>
    <title>WebSocket测试</title>
</head>
<body>
    <div>
        <h2>WebSocket测试页面</h2>
        <div>
            <input type="text" id="messageInput" placeholder="输入消息">
            <button onclick="sendMessage()">发送</button>
        </div>
        <div id="messages" style="margin-top: 20px;"></div>
    </div>
    <script>
        let ws = null;
        function connect() {
            ws = new WebSocket('ws://localhost:8080/websocket');
            ws.onopen = function() {
                console.log('WebSocket连接已建立');
                appendMessage('系统消息:连接已建立');
            };
            ws.onmessage = function(event) {
                appendMessage('收到消息:' + event.data);
            };
            ws.onclose = function() {
                console.log('WebSocket连接已关闭');
                appendMessage('系统消息:连接已关闭');
            };
            ws.onerror = function(error) {
                console.error('WebSocket错误:', error);
                appendMessage('系统消息:连接发生错误');
            };
        }
        function sendMessage() {
            const messageInput = document.getElementById('messageInput');
            const message = messageInput.value;
            if (ws && message) {
                ws.send(message);
                appendMessage('发送消息:' + message);
                messageInput.value = '';
            }
        }
        function appendMessage(message) {
            const messagesDiv = document.getElementById('messages');
            const messageElement = document.createElement('div');
            messageElement.textContent = message;
            messagesDiv.appendChild(messageElement);
        }
        // 页面加载完成后连接WebSocket
        window.onload = connect;
    </script>
</body>
</html>

6. 测试WebSocket功能

  • 启动 SpringBoot 应用
  • 打开多个浏览器窗口访问 HTML 页面
  • 在任意窗口发送消息,观察其他窗口是否收到消息
  • 使用 POST 请求测试广播功能:
curl -X POST http://localhost:8080/api/websocket/broadcast \
     -H "Content-Type: text/plain" \
     -d "这是一条广播消息"

7. 进阶功能

7.1 心跳检测

为了保持WebSocket连接的稳定性,可以实现心跳机制:

    @Scheduled(fixedRate = 10000) // 每10秒发送一次心跳,需要启动类或配置类上添加@EnableScheduling
    public void sendHeartbeat() {
        String heartbeat = "heartbeat";
        sessions.values().forEach(session -> {
            try {
                session.sendMessage(new TextMessage(heartbeat));
            } catch (IOException e) {
                log.error("发送心跳消息失败", e);
            }
        });
    }

7.2 消息重试机制

当消息发送失败时,实现重试机制:

public void sendMessageWithRetry(WebSocketSession session, String message, int maxRetries) {
    int retryCount = 0;
    while (retryCount < maxRetries) {
        try {
            session.sendMessage(new TextMessage(message));
            return;
        } catch (IOException e) {
            retryCount++;
            log.error("消息发送失败,尝试重试 {}/{}", retryCount, maxRetries);
            try {
                Thread.sleep(1000);
            } catch (InterruptedException ie) {
                Thread.currentThread().interrupt();
                break;
            }
        }
    }
    log.error("消息发送失败,达到最大重试次数");
}

8. 注意事项

连接管理

  • 及时清理断开的连接
  • 实现最大连接数限制
  • 考虑使用连接池管理WebSocket连接

安全性

  • 实现用户认证
  • 添加消息加密
  • 设置适当的跨域策略

性能优化

  • 使用消息队列处理大量消息
  • 实现消息压缩
  • 控制消息大小

错误处理

  • 完善异常处理机制
  • 实现日志记录
  • 添加监控告警

9. 总结

SpringBoot 3 整合 WebSocket 提供了一种高效的实时通信解决方案。通过本文的配置和示例,你可以快速实现:

  • WebSocket服务器端配置
  • 客户端连接管理
  • 消息收发处理
  • 广播功能
  • 心跳检测
  • 错误处理

这些功能可以作为构建实时应用的基础,如在线聊天、实时数据推送、游戏等场景。根据具体需求,你可以在此基础上扩展更多功能。

参考资料

到此这篇关于SpringBoot3整合WebSocket指南的文章就介绍到这了,更多相关SpringBoot3整合WebSocket内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Java连接MySQL数据库并实现数据交互功能

    Java连接MySQL数据库并实现数据交互功能

    在现代应用中,数据库是不可或缺的一部分,Java 作为一种广泛使用的编程语言,提供了丰富的 API 来与各种数据库进行交互,本文将详细介绍如何在 Java 中连接 MySQL 数据库,并实现基本的数据交互功能,需要的朋友可以参考下
    2024-10-10
  • Java web xml文件读取解析方式

    Java web xml文件读取解析方式

    这篇文章主要介绍了Java web xml文件读取解析方式,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-03-03
  • 过滤器 和 拦截器的 6个区别(别再傻傻分不清了)

    过滤器 和 拦截器的 6个区别(别再傻傻分不清了)

    这篇文章主要介绍了过滤器 和 拦截器的 6个区别,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-06-06
  • SpringIOC DI循环依赖实例详解

    SpringIOC DI循环依赖实例详解

    这篇文章主要介绍了SpringIOC——DI循环依赖,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-03-03
  • java阿拉伯数字转中文数字

    java阿拉伯数字转中文数字

    这篇文章主要为大家详细介绍了java实现阿拉伯数字转换为中文数字,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-04-04
  • JAVA中值类型和引用类型的区别

    JAVA中值类型和引用类型的区别

    在java开发中经常会遇到值类型和引用类型知识,但是有很多朋友不清楚java中值类型和引用类型的区别,今天小编通过本文给大家介绍下
    2017-02-02
  • 浅析Java 数据结构常用接口与类

    浅析Java 数据结构常用接口与类

    本篇文章主要介绍了Java中的数据结构,Java工具包提供了强大的数据结构。需要的朋友可以参考下
    2017-04-04
  • Java如何发起http请求的实现(GET/POST)

    Java如何发起http请求的实现(GET/POST)

    这篇文章主要介绍了Java如何发起http请求的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-03-03
  • JAVA+Struts2获取服务器地址的方法

    JAVA+Struts2获取服务器地址的方法

    这篇文章主要介绍了JAVA+Struts2获取服务器地址的方法,是Struts2的一个简单应用,具有一定的借鉴与参考价值,需要的朋友可以参考下
    2014-11-11
  • Spring中bean的继承与抽象代码示例

    Spring中bean的继承与抽象代码示例

    这篇文章主要介绍了Spring中bean的继承与抽象代码示例,涉及abstract 属性,bean实例化,子bean 与普通bean等相关内容,代码示例中注释比较详细,需要的朋友可以参考下。
    2017-09-09

最新评论