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日

相关文章

  • 解决JS请求服务器gbk文件乱码的问题

    当我们使用JavaScript从服务器请求文本数据时,可能会遇到文本编码不符合UTF-8(如GBK)的情况,导致在浏览器端显示出错了,我们需要对此进行处理。 1. 了解传统的字符编码方式 在 Web 开发初期,世界各地的计算机都有自己的字符编码规范,因此引起了字符编码混乱的情况。后来,Unicode 规范提出来,尝试解决全球字符集的问题,UTF-8 字符编码…

    JavaScript 2023年5月19日
    00
  • JS中常用的输出方式(五种)

    当我们在编写JavaScript代码时,需要将程序运行的结果在控制台或者网页上输出,此时就需要使用JavaScript提供的输出函数。JS中常用的输出方式有以下五种: 1. alert() 语法:alert(要输出的内容); 作用:在页面上弹出一个消息框,并在里面输出指定的内容。 示例: alert("您的操作有误,请重新输入!"); /…

    JavaScript 2023年5月28日
    00
  • js中的面向对象之对象常见创建方法详解

    JS中的面向对象之对象常见创建方法详解 1. 对象字面量 对象字面量是创建对象的一种简单方法,它是用一对花括号{}括起来的数据结构,其中包含一个或多个属性和属性值,属性名和属性值用冒号:”分隔,多个属性之间用逗号,`分隔。 示例代码: let student = { name: ‘Tom’, age: 20, gender: ‘male’, sayHi: f…

    JavaScript 2023年5月27日
    00
  • Javascript Date setUTCMinutes() 方法

    以下是关于JavaScript Date对象的setUTCMinutes()方法的完整攻略,包括两个示例说明。 JavaScript Date对象的setUTCMinutes()方法 JavaScript的setUTCMinutes()方法设置对象UTC分钟部分。该方法接受一个整数,表示要设置的UTC分钟。如果该参数超出了JavaScript所能表示的范围,…

    JavaScript 2023年5月11日
    00
  • javascript实现实时输出当前的时间

    下面是详细讲解如何用JavaScript实现实时输出当前时间的攻略。 步骤一:获取当前时间 JavaScript内置了Date对象,可以通过该对象的各种方法获取当前系统时间。其中,可以使用new Date()方法创建一个Date对象,该对象可以返回包含当前日期和时间的Date对象。例如: let now = new Date(); 这将创建一个表示当前日期和…

    JavaScript 2023年5月27日
    00
  • 由 element.appendChild(newNode) ,谈开去

    当我们使用 JavaScript 编程时,经常需要修改 HTML 元素的结构,其中一个常用的方法就是将一个新的节点添加到现有节点的子节点列表中。这个操作可以通过 appendChild() 方法来完成。 1. element.appendChild(newNode) 的使用方法 1.1 参数 newNode:要添加的新节点。可以是一个元素节点、文本节点、注释…

    JavaScript 2023年6月10日
    00
  • Javascript中的return作用及javascript return关键字用法详解

    当程序执行一个函数时,可能需要将函数的计算结果返回给调用函数的地方,这种情况下就需要使用return语句了。 在JavaScript中,return语句用于将函数执行结果返回给调用者。一旦return语句执行,函数将立即停止执行,并将return语句的值返回给调用者。如果没有指定返回值,函数将默认返回undefined。 return语句的语法格式 retu…

    JavaScript 2023年5月27日
    00
  • JS判断字符串包含的方法

    JS中判断字符串是否包含指定字符或字符串的方法有多种。下面我将为你详细讲解常见的几种方法,包括 includes()、indexOf()、search()、match()、正则表达式。同时,你可以参考下面的示例,更好地理解这些方法。 includes() includes()是ES6提供的新增方法。该方法用于判断一个字符串中是否包含指定字符或字符串,并返回B…

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