SpringBoot+WebSocket实现即时通讯的方法详解

yizhihongxing

以下是详细讲解“SpringBoot+WebSocket实现即时通讯的方法详解”的完整攻略。

一、前置知识

在学习本篇攻略之前需要了解以下知识点:

  1. SpringBoot框架的基础知识
  2. WebSocket协议的相关知识
  3. Springboot整合WebSocket的基础知识

二、SpringBoot集成WebSocket的步骤

1.创建SpringBoot项目

我们首先需要创建一个新的SpringBoot项目,可以使用Spring Initializr来帮助我们快速生成一个基础项目,推荐使用Maven或Gradle来管理项目。

2.添加WebSocket依赖

在项目的pom.xml文件中添加以下依赖:

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

3.创建WebSocket配置类

在项目的src/main/java目录下创建一个新的package,命名为com.example.websocket.config,然后在该package下创建WebSocketConfig类,代码如下所示:

@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer {

    @Override
    public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
        registry.addHandler(new MyHandler(), "/myHandler")
                .addInterceptors(new HandshakeInterceptor() {
                    @Override
                    public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response,
                                                   WebSocketHandler wsHandler, Map<String, Object> attributes) throws Exception {
                        // 处理握手前的逻辑
                        return true;
                    }

                    @Override
                    public void afterHandshake(ServerHttpRequest request, ServerHttpResponse response,
                                                WebSocketHandler wsHandler, Exception exception) {
                        // 处理握手后的逻辑
                    }
                }).setAllowedOrigins("*");
    }

    class MyHandler extends TextWebSocketHandler {

        @Override
        public void handleTextMessage(WebSocketSession session, TextMessage message) throws IOException {
            // 处理消息的逻辑
        }
    }
}

在上述代码中:

  • @Configuration:该注解表示将该类声明为一个配置类。
  • @EnableWebSocket:该注解表示开启WebSocket支持。
  • WebSocketConfigurer:该接口定义了WebSocket的配置信息的回调方法。
  • HandlerMapping:WebSocket的处理映射。
  • HandshakeInterceptor:WebSocket的握手拦截器。
  • MyHandler:自定义的WebSocket处理器,继承自TextWebSocketHandler。

4.编写WebSocket前端代码

Websocket协议是基于TCP的,所以我们需要使用一个WebSocket客户端来测试我们的WebSocket服务。在前端HTML页面中添加以下代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>WebSocket Example</title>
    <script>
        var socket = new WebSocket("ws://localhost:8080/echo");

        socket.onopen = function(event) {
            console.log("WebSocket opened");
            console.log(event);
        };

        socket.onmessage = function(event) {
            console.log("WebSocket received message: " + event.data);
        };

        socket.onclose = function(event) {
            console.log("WebSocket closed");
        };
    </script>
</head>
<body>
    <h1>WebSocket Example</h1>
    <p>WebSocket connection status: <span id="status">unknown</span></p>
</body>
</html>

在上述代码中,我们使用了WebSocket的JavaScript API,其中:

  • WebSocket:WebSocket的构造函数,用于创建一个WebSocket客户端实例。
  • onopen:当WebSocket连接建立时触发。
  • onmessage:当WebSocket收到消息时触发。
  • onclose:当WebSocket连接关闭时触发。

5.测试WebSocket服务

启动我们的SpringBoot项目,打开Chrome浏览器,并访问前面编写的HTML页面。在控制台中可以看到WebSocket连接成功的日志。

三、示例说明

1.代码示例一:群聊功能

我们可以使用WebSocket实现一个简单的群聊功能。

首先,我们需要在后端代码中编写一个WebSocket处理器:

class MyHandler extends TextWebSocketHandler {

    private static final List<WebSocketSession> sessions = new ArrayList<>();

    @Override
    public void handleTextMessage(WebSocketSession session, TextMessage message) throws IOException {
        for (WebSocketSession s : sessions) {
            if (!s.equals(session)) {
                s.sendMessage(message);
            }
        }
    }

    @Override
    public void afterConnectionEstablished(WebSocketSession session) throws Exception {
        sessions.add(session);
    }

    @Override
    public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
        sessions.remove(session);
    }
}

上述代码中:

  • sessions:保存所有已连接的WebSocketSession对象。
  • handleTextMessage:处理收到的WebSocket消息,并广播到所有已连接的WebSocketSession对象。
  • afterConnectionEstablished:当有新的WebSocket连接建立时将其添加到sessions列表中。
  • afterConnectionClosed:当有WebSocket连接关闭时,从sessions列表中将其移除。

此外,还需要在WebSocketConfig类中将MyHandler注册到WebSocket中:

registry.addHandler(new MyHandler(), "/simpleChat").setAllowedOrigins("*");

在前端代码中,我们可以使用以下JavaScript代码来触发发送消息:

<body>
    <h1>群聊</h1>
    <div>
        <textarea id="message" rows="3"></textarea>
        <button onclick="sendMessage()">发送</button>
    </div>
    <ul id="messages"></ul>

    <script>
        var socket = new WebSocket("ws://localhost:8080/simpleChat");
        var messageInput = document.getElementById("message");
        var messageList = document.getElementById("messages");

        socket.onmessage = function(event) {
            var message = event.data;
            messageList.innerHTML += "<li>" + message + "</li>";
        };

        function sendMessage() {
            var message = messageInput.value;
            socket.send(message);
            messageInput.value = "";
        }
    </script>
</body>

可以看到,我们在HTML页面中添加了一个文本框、一个发送按钮和一个消息列表。当用户点击发送按钮时,JavaScript代码调用WebSocket的send方法发送消息。同时,当WebSocket接收到消息时,JavaScript代码将消息添加到页面的消息列表中。这样就实现了一个简单的群聊应用。

2.代码示例二:在线聊天室

我们可以使用WebSocket实现一个在线聊天室。

首先,我们需要在后端代码中编写一个WebSocket处理器:

class ChatHandler extends TextWebSocketHandler {

    private static final Map<String, WebSocketSession> connections = new ConcurrentHashMap<>();

    @Override
    public void handleTextMessage(WebSocketSession session, TextMessage message) throws IOException {
        String payload = message.getPayload();
        ObjectMapper objectMapper = new ObjectMapper();
        ChatMessage chatMessage = objectMapper.readValue(payload, ChatMessage.class);
        String recipient = chatMessage.getRecipient();
        if (recipient == null) {
            broadcastMessage(chatMessage);
        } else {
            sendMessageToUser(recipient, chatMessage);
        }
    }

    private void broadcastMessage(ChatMessage chatMessage) throws IOException {
        String payload = chatMessage.toJsonString();
        TextMessage message = new TextMessage(payload);
        for (WebSocketSession session : connections.values()) {
            session.sendMessage(message);
        }
    }

    private void sendMessageToUser(String userId, ChatMessage chatMessage) throws IOException {
        String payload = chatMessage.toJsonString();
        TextMessage message = new TextMessage(payload);
        WebSocketSession session = connections.get(userId);
        if (session != null && session.isOpen()) {
            session.sendMessage(message);
        }
    }

    @Override
    public void afterConnectionEstablished(WebSocketSession session) throws Exception {
        String userId = session.getUri().getQuery().split("=")[1];
        connections.put(userId, session);
    }

    @Override
    public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
        for (Map.Entry<String, WebSocketSession> entry : connections.entrySet()) {
            if (entry.getValue().equals(session)) {
                connections.remove(entry.getKey());
            }
        }
    }
}

上述代码中:

  • connections:保存所有已连接的WebSocketSession对象。
  • handleTextMessage:处理收到的WebSocket消息,并根据消息中的recipient字段决定是广播消息还是向某个用户发送消息。
  • broadcastMessage:广播消息到所有已连接的WebSocketSession对象。
  • sendMessageToUser:向指定用户发送消息。
  • afterConnectionEstablished:当有新的WebSocket连接建立时从连接URI中获取用户ID,将其添加到connections中。
  • afterConnectionClosed:当有WebSocket连接关闭时,从connections中将其移除。

此外,还需要在WebSocketConfig类中将ChatHandler注册到WebSocket中:

registry.addHandler(new ChatHandler(), "/chat").setAllowedOrigins("*");

在前端代码中,我们可以使用以下JavaScript代码来触发发送消息:

<body>
    <h1>在线聊天室</h1>

    <label for="userId">用户名:</label>
    <input type="text" id="userId"/>
    <button onclick="connect()">登录</button>

    <div style="display: none" id="chat">
        <hr/>
        <div>
            <ul id="messages"></ul>
            <br/>
            <div>
                <label for="recipient">私聊对象:</label>
                <input type="text" id="recipient"/>
            </div>
            <br/>
            <div>
                <textarea id="message" rows="3"></textarea>
                <button onclick="sendMessage()">发送</button>
            </div>
        </div>
    </div>

    <script>
        var userIdInput = document.getElementById("userId");
        var chatDiv = document.getElementById("chat");
        var messagesList = document.getElementById("messages");
        var recipientInput = document.getElementById("recipient");
        var messageInput = document.getElementById("message");
        var chatSocket = null;

        function connect() {
            var userId = userIdInput.value;
            if (userId.trim() !== "") {
                chatDiv.style.display = "block";
                var host = window.location.hostname;
                chatSocket = new WebSocket("ws://" + host + ":8080/chat?userId=" + userId);
                chatSocket.onmessage = function(event) {
                    var payload = event.data;
                    var chatMessage = JSON.parse(payload);
                    var sender = chatMessage.sender;
                    var message = chatMessage.message;
                    var item = "<li>";
                    if (sender !== "") {
                        item += sender + ": ";
                    }
                    item += message + "</li>";
                    messagesList.innerHTML += item;
                };
            }
        }

        function disconnect() {
            chatSocket.close();
            chatDiv.style.display = "none";
        }

        function sendMessage() {
            var message = messageInput.value;
            var recipient = recipientInput.value;
            var payload = JSON.stringify({recipient: recipient, message: message});
            chatSocket.send(payload);
            messageInput.value = "";
        }
    </script>
</body>

可以看到,我们在HTML页面中添加了用户名输入框、登录按钮、聊天界面和在线用户列表。当用户在登录框中输入名字并点击登录按钮时,JavaScript代码会通过WebSocket连接到后端并发送用户ID。发起连接后,聊天界面会显示出来。用户可以在输入框中输入消息并点击发送按钮。当有新的消息到来时,JavaScript代码会将其添加到在线用户列表和消息列表中。

四、总结

本篇攻略中,我们讲解了如何使用SpringBoot和WebSocket协议实现即时通讯的方法。具体来说,我们分别讲解了SpringBoot集成WebSocket的步骤和两个示例代码。实现即时通讯功能是很有趣的,希望可以帮助读者更好地理解WebSocket和SpringBoot的使用。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:SpringBoot+WebSocket实现即时通讯的方法详解 - Python技术站

(0)
上一篇 2023年5月28日
下一篇 2023年5月28日

相关文章

  • vue项目实战总结篇

    Vue项目实战总结篇 总述 本文介绍了Vue项目的实战总结,包括项目的搭建、组件的编写、路由的配置以及API的获取处理等方面。项目通过一个在线购物网站的实例来展示Vue框架在实战应用中的优雅与高效。 项目搭建 在项目搭建方面,我们可以使用Vue CLI工具来快速生成项目框架。具体步骤如下: 安装Vue CLI,可以使用命令 npm install -g @v…

    Vue 2023年5月28日
    00
  • vuex入门教程,图文+实例解析

    Vuex入门教程,图文+实例解析 什么是Vuex Vuex是一个为大型单页面应用程序提供的状态管理模式,它将整个应用程序的数据状态分离出来,集中在一个数据存储库中,使应用程序的状态变得可预测。Vuex提供了一个集中式的存储空间,其中包含所有组件都可以访问的状态。 Vuex的核心概念 Vuex中的核心概念包括状态(state)、操作(mutations)、动作…

    Vue 2023年5月28日
    00
  • JS简单实现点击按钮或文字显示遮罩层的方法

    下面是JS简单实现点击按钮或文字显示遮罩层的方法的完整攻略: 1. 初步思路 实现点击按钮或文字显示遮罩层,我们需要实现以下两个步骤: 点击按钮或文字后,触发显示遮罩层的函数 显示遮罩层,覆盖整个页面或部分页面 2. 实现过程 2.1 触发函数 我们可以通过以下两种方式触发函数: 2.1.1 绑定事件 我们可以通过JS绑定事件,当用户点击按钮或文字时触发事件…

    Vue 2023年5月28日
    00
  • vue在取对象长度length时候出现undefined的解决

    当使用Vue框架的语法时,在某些情况下从一个对象中获取其长度属性时,可能会返回undefined。这通常是由于Vue对象中有未定义的属性造成的。下面是解决这种问题的方法。 方法一:使用计算属性 我们可以使用计算属性来获取Vue对象的长度。通过计算属性,我们可以遍历对象并返回正确的长度。 <template> <div>{{ objec…

    Vue 2023年5月27日
    00
  • vue3响应式Object代理对象的读取示例详解

    以下是“vue3响应式Object代理对象的读取示例详解”的攻略。 1. 什么是Vue3响应式Object代理对象 在Vue3中,响应式Object代理对象是指通过Vue3提供的reactive方法和ref方法,将JavaScript对象转换为Vue3响应式代理对象,这样当对象发生变化时,Vue会自动响应地更新视图,从而实现数据的双向绑定。 2. 如何读取V…

    Vue 2023年5月28日
    00
  • vue实现指定日期之间的倒计时

    下面是关于”Vue 实现指定日期之间的倒计时”的完整攻略: 概述 倒计时是很常见的一项功能,用来实现类似于限时抢购、秒杀活动等功能。在 Vue 中实现倒计时可以使用 Vue 的计算属性或者 Watch 监听器来实现,同时还需要使用 JavaScript 中的 getTime 方法来获取时间戳以实现倒计时的功能。 步骤 下面是实现倒计时的一些步骤: 1.在 V…

    Vue 2023年5月28日
    00
  • 超简单的Vue.js环境搭建教程

    超简单的Vue.js环境搭建教程 1. 确认开发环境 在开始之前,需要确认本地电脑是否已经安装了 Node.js,如果没有,请下载并安装它。安装完成后,使用命令 node -v和npm -v 确认是否安装成功。 2. 安装Vue的脚手架 在Vue中我们可以使用脚手架工具vue-cli快速构建项目,首先需要使用npm安装vue-cli。在命令行中输入下面的命令…

    Vue 2023年5月28日
    00
  • vue与django集成打包的实现方法

    实现 Vue 和 Django 的集成打包,需要以下步骤: 1. 创建 Vue 应用程序 首先,我们需要创建一个 Vue 应用程序。在使用 Vue CLI 创建应用程序后,确保在命令行中运行npm run build 命令来打包应用程序。 $ vue create my-vue-app $ cd my-vue-app $ npm install $ npm …

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