Spring boot项目整合WebSocket方法

下面是关于Spring boot整合WebSocket的完整攻略。

环境准备

  1. JDK 1.8及以上版本
  2. Maven 3.2及以上版本
  3. Spring Boot 2.x版本
  4. IDE:Eclipse、IDEA

依赖配置

在Spring Boot项目中开启WebSocket功能需要引入相关依赖,添加以下依赖到项目的pom.xml文件中:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-websocket</artifactId>
</dependency>

WebSocket配置

自定义WebSocket处理器

自定义一个Websocket处理器来处理WebSocket连接和消息:

@Component
public class MyWebSocketHandler extends TextWebSocketHandler {

    private static final Logger LOGGER = LoggerFactory.getLogger(MyWebSocketHandler.class);

    // 保存在线用户列表
    private static final Map<String, WebSocketSession> USERS = new ConcurrentHashMap<>();

    // 添加一个新用户到在线列表
    @Override
    public void afterConnectionEstablished(WebSocketSession session) throws Exception {
        String username = (String) session.getAttributes().get("username");
        LOGGER.info("新用户 {} 加入聊天室", username);
        USERS.put(username, session);
    }

    // 处理用户发送的消息
    @Override
    protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
        LOGGER.info("收到用户 {} 发送的消息:{}", session.getAttributes().get("username"), message.getPayload());
        sendMessageToAllUsers(session, message.getPayload()); // 群发消息
    }

    // 从在线列表中删除用户并断开WebSocket连接
    @Override
    public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
        String username = (String) session.getAttributes().get("username");
        LOGGER.info("用户 {} 离开聊天室,断开WebSocket连接", username);
        USERS.remove(username);
    }

    // 群发消息
    private void sendMessageToAllUsers(WebSocketSession fromUser, String message) throws IOException {
        TextMessage textMessage = new TextMessage(message);
        for (Map.Entry<String, WebSocketSession> entry : USERS.entrySet()) {
            WebSocketSession session = entry.getValue();
            if (!session.isOpen()) {
                continue;
            }
            if (session == fromUser) {
                continue;
            }
            session.sendMessage(textMessage);
        }
    }
}

WebSocket配置类

定义一个WebSocket配置类来设置WebSocket的相关信息:

@Configuration
@EnableWebSocket
public class MyWebSocketConfig implements WebSocketConfigurer {

    @Autowired
    private MyWebSocketHandler myWebSocketHandler;

    @Override
    public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
        registry.addHandler(myWebSocketHandler, "/ws").setAllowedOrigins("*"); // 配置WebSocket端点,允许跨域访问
    }
}

Controller层

在Controller层中添加一个方法来接收WebSocket连接,并将用户信息存储在WebSocketSession中:

@Controller
public class UserController {

    @GetMapping("/login")
    public String login(String username, HttpServletRequest request) {
        request.getSession().setAttribute("username", username); // 将username保存到session中
        return "chat";
    }

    @Autowired
    private SimpMessagingTemplate messagingTemplate;

    // 处理WebSocket连接请求
    @MessageMapping("/send")
    public void handleWebSocketMessage(Principal principal, ChatMessage message) throws Exception {
        String fromUser = principal.getName(); // 获取发送者的用户名
        String toUser = message.getToUser();
        if (StringUtils.isBlank(toUser)) {
            messagingTemplate.convertAndSend("/topic/public", new ChatMessage(fromUser, message.getContent())); // 广播消息
        } else {
            messagingTemplate.convertAndSendToUser(toUser, "/queue/message", new ChatMessage(fromUser, message.getContent())); // 指定用户发送消息
        }
    }
}

页面展示

使用JSP页面来展示聊天页面,用户在登录页面输入用户名后,跳转到聊天室页面:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Spring Boot WebSocket Demo</title>
    <style>
        .messageForm {
            display: flex;
            margin-bottom: 10px;
        }

        .messageInput {
            flex-grow: 1;
            margin-right: 5px;
        }

        .messageButton {
            width: 80px;
        }
    </style>
</head>
<body>
    <div class="container">
        <h1>Spring Boot WebSocket Demo</h1>
        <hr/>
        <h2>Welcome <%=session.getAttribute("username")%></h2>
        <div id="chatBox">
        </div>
        <div class="messageForm">
            <input type="text" id="messageInput" class="messageInput" placeholder="请输入你的消息...">
            <button type="button" class="messageButton" onclick="sendMessage()">发送</button>
        </div>
    </div>
    <script src="/webjars/jquery/3.3.1/jquery.min.js"></script>
    <script src="/webjars/sockjs-client/1.3.0/sockjs.min.js"></script>
    <script src="/webjars/stomp-websocket/2.3.3/stomp.min.js"></script>
    <script>
        // 连接WebSocket服务器
        var stompClient = Stomp.over(new SockJS('/ws'));
        stompClient.connect({}, function (frame) {
            console.log('Connected: ' + frame);
            stompClient.subscribe('/user/queue/message', function (response) {
                showMessage(JSON.parse(response.body));
            });
            stompClient.subscribe('/topic/public', function (response) {
                showMessage(JSON.parse(response.body));
            });
        });

        // 显示消息
        function showMessage(message) {
            var $chatBox = $('#chatBox');
            var $messageDiv = $('<div></div>');
            $messageDiv.html(message.fromUser + ' : ' + message.content);
            $chatBox.append($messageDiv);
        }

        // 发送消息
        function sendMessage() {
            var $messageInput = $('#messageInput');
            var message = $messageInput.val();
            $messageInput.val('');
            stompClient.send("/app/send", {}, JSON.stringify({'content': message}));
        }
    </script>
</body>
</html>

示例1:测试广播消息

假设我们有三个用户A、B、C登录到聊天室:

  • 用户A在聊天窗口输入"Hello, everyone!",发送广播消息;
  • 用户B、C将收到该消息。

示例2:测试点对点消息

假设我们有两个用户A、B登录到聊天室:

  • 用户A在聊天窗口输入"@B Hello, B!",发送点对点消息;
  • 用户B将收到该消息。

以上就是完整的Spring Boot项目整合WebSocket方法的攻略。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Spring boot项目整合WebSocket方法 - Python技术站

(0)
上一篇 2023年6月11日
下一篇 2023年6月11日

相关文章

  • 如何快速高效创建JavaScript 一维数组方法详解

    当我们需要存储一组相关数据时,数组是JavaScript中最常用的数据类型之一。创建JavaScript一维数组非常简单,我们只需要将不同的数值或字符串用逗号隔开即可。但是,当数组中数据很多时,我们需要更高效,更便利地来创建数组。 下面是创建JavaScript一维数组的一些方法详解。 1. 直接赋值法 这是最基本的方法,我们可以直接在代码中定义值为数组类型…

    JavaScript 2023年5月27日
    00
  • 一文详解最常见的六种跨域解决方案

    一文详解最常见的六种跨域解决方案 Web应用程序中,由于同源策略的限制,导致跨域问题成为Web开发过程中的一个热门话题。本文将详细讲解最常见的六种跨域解决方案,分别是: JSONP CORS postMessage document.domain iframe 代理服务器 1. JSONP JSONP 是最容易学习和使用的解决跨域问题的方式之一。JSONP …

    JavaScript 2023年6月11日
    00
  • 详解JSON.stringify()的5个秘密特性

    详解JSON.stringify()的5个秘密特性 JSON.stringify() 是将一个 JavaScript 对象或值转换为 JSON 字符串的方法。但是,如果您不了解 JSON.stringify() 的所有“秘密特性”,则无法在实际开发中充分利用它的性能和灵活性。以下是5个最重要的“秘密特性”。 1. JSON.stringify() 可以通过选…

    JavaScript 2023年5月27日
    00
  • JavaScript前端开发时数值运算的小技巧

    下面我来为大家详细讲解一下”JavaScript前端开发时数值运算的小技巧”的完整攻略。 标题 JavaScript前端开发时数值运算的小技巧 缩略语 在JS开发中,经常会用到缩略语如下: Math.ceil() 向上取整 Math.floor() 向下取整 Math.round() 四舍五入 数值运算技巧 在计算浮点数时使用toFixed() 当涉及到浮点…

    JavaScript 2023年6月10日
    00
  • JavaScript实现多文件下载方法解析

    JavaScript实现多文件下载方法解析 在前端开发中,我们可能会遇到需要同时下载多个文件的场景。如果只是下载单个文件,直接使用a标签即可;但是如果需要同时下载多个文件,就需要使用JavaScript来实现了。 1. 使用for循环下载多个文件 首先,我们可以通过for循环来实现多个文件的下载。下面是代码示例: function downloadFiles…

    JavaScript 2023年5月27日
    00
  • Javascript 面向对象 重载

    JavaScript 是一种面向对象的编程语言,它支持函数重载,即同一函数名字,参数不同,对应的实现不同,JavaScript 可以通过这种方式实现函数重载。 什么是面向对象 面向对象(Object-Oriented Programming)是一种编程思想,它把对象作为程序的基本单元,将程序中的数据和操作数据的方法绑定在一起,以及保护数据的安全性。JavaS…

    JavaScript 2023年5月27日
    00
  • Js,alert出现乱码问题的解决方法

    让我为你详细讲解如何解决“Js,alert出现乱码问题”。 问题描述: 在 JavaScript 中,当我们在 alert 函数中传入一个包含中文字符的字符串时,可能会出现乱码或者无法正常显示的情况,这给我们的开发和调试带来了很大的困扰。 解决方法: 1.使用 escape 函数进行编码 JavaScript 的 escape 函数可以将字符串转义成 ASC…

    JavaScript 2023年5月19日
    00
  • JavaScript setinterval延迟一秒解决方案

    当我们在使用JavaScript代码的时候,我们可能会遇到需要执行定时任务的情况。而在一些情况下,我们需要在定时任务中等待一定的时间,再执行后续的操作。这时就可以使用setInterval延迟一定时间进行操作。但是,要注意setInterval不是严格间隔时间执行,而是间隔一段时间后才会执行。下面是针对“JavaScript setInterval延迟一秒解…

    JavaScript 2023年6月11日
    00
合作推广
合作推广
分享本页
返回顶部