Advertisement

手把手教你入门vue+springboot开发(十)--springboot集成WebSocket

阅读量:

这篇文章主要介绍了如何在Spring Boot中集成WebSocket协议,实现后端与前端之间的消息通信。文章详细讲解了在后端实现WebSocket服务端和客户端的配置与实现,包括使用org.springframework.boot-starter-websocket依赖、配置WebSocketConfig和WebServerEndpoint类,以及如何通过ObjectMapper将Java对象转换为JSON格式进行通信。此外,文章还介绍了前端如何通过修改App.vue文件实现WebSocket客户端的连接与消息处理,并通过Postman进行了调试,验证了通信的正确性。文章最后总结了整个实现过程,并提到后续将介绍Token的使用。

文章目录

  • 引言
  • 第一部分Spring Boot WebSocket集成
    • 第一部分第一节WebSocket服务端实现
    • 第一部分第二节业务逻辑实现
    • 第一部分第三节ObjectMapper的作用
  • 第二部分后端代码实现
    • 第二部分第一节WebSocket服务端实现

    • 第二部分第二节业务逻辑实现

    • 第二部分第三节ObjectMapper的作用

    • 三、前端代码实现

    • 四、postman调试

    • 总结


前言

在B/S开发的某些业务场景中,后端需要向用户推送特定事件信息,例如,当某个用户登录或退出时,后端应通知所有当前登录的用户。显然,HTTP协议无法满足这一需求,于是,我们可以采用WebSocket协议,并探讨如何在Spring Boot中集成该协议以实现上述功能。


一、springboot集成WebSocket

pom.xml增加websocket依赖,如下:

复制代码
    <!--websocket依赖-->
    <dependency>
    	<groupId>org.springframework.boot</groupId>
    	<artifactId>spring-boot-starter-websocket</artifactId>
    </dependency>

二、后端代码实现

1.WebSocket服务端实现

开发一个WebSocket包,并新增WebSocketConfig和WebServerEndpoint两个类模块,以构建WebSocket服务端接口。

复制代码
    package com.example.demo.websocket;
    
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.web.socket.server.standard.ServerEndpointExporter;
    
    // 需要注入Bean的话必须声明为配置类
    @Configuration
    public class WebSocketConfig {
    @Bean
    public ServerEndpointExporter serverEndpointExporter(){
        return new ServerEndpointExporter();
    }
    }

WebServerEndpoint.java代码如下:

复制代码
    package com.example.demo.websocket;
    
    import jakarta.websocket.OnClose;
    import jakarta.websocket.OnMessage;
    import jakarta.websocket.OnOpen;
    import jakarta.websocket.Session;
    import jakarta.websocket.server.ServerEndpoint;
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.stereotype.Component;
    import java.io.IOException;
    import java.util.Map;
    import java.util.concurrent.ConcurrentHashMap;
    
    // 监听哪些客户端来连接了WebSocket服务端
    // 监听websocket地址 /myWs
    @ServerEndpoint("/myWs")
    @Component
    @Slf4j
    public class WebServerEndpoint {
    
    // 因为可能有多个客户端所以这里需要保证线程安全
    static Map<String, Session> sessionMap = new ConcurrentHashMap<>();
    
    // 建立连接时执行的操作
    @OnOpen
    public void onOpen(Session session){   // 每个websocket连接对于服务端来说都是一个Session
        sessionMap.put(session.getId(),session);
        log.info("websocket is open");
    }
    
    /** * 收到客户端消息时执行的操作
     * @param text 接受到客户端的消息
     * @return 返回给客户端的消息
     */
    @OnMessage
    public String onMessage(String text){
        log.info("收到一条新消息: " + text);
        return "收到 !";
    }
    
    // 连接关闭时执行的操作
    @OnClose
    public void onClose(Session session){
        sessionMap.remove(session.getId());
        log.info("websocket is close");
    }
    
    public void sendmsg(String msg) {
        if(sessionMap.isEmpty()){return;}
        try {
            for (String key : sessionMap.keySet()) { // 给所有客户端发送消息
                sessionMap.get(key).getBasicRemote().sendText(msg);
                log.info("websocket sendmsg:" + msg);
            }
        }catch (IOException e) {
            e.printStackTrace();
        }
    }
    }

该 WebSocket 协议提供了多个事件回调函数,支持服务端与客户端双向通信。onopen 事件:当服务端响应 WebSocket 连接请求时,该事件触发并建立连接,其对应的回调函数名为 onopen。onmessage 事件:在接收到消息时触发,其对应的回调函数名为 onmessage。onerror 事件:在响应意外故障时触发,其对应的回调函数名为 onerror。onclose 事件:当 WebSocket 连接关闭时触发,其对应的回调函数名为 onclose。一旦发生连接关闭,客户端与服务器将无法进行消息接收或发送。通过 sessionMap.get(key).getBasicRemote().sendText(msg) 方法,服务端能够向指定的客户端发送消息。

2.业务逻辑实现

在用户登录成功后向其他已登录用户推送登录事件,在WebSocket发送事件的业务逻辑上,应避免将逻辑放置于UserController中,而应将其置于UserService中。因为Controller主要负责与前端交互,而Service则负责具体业务处理。

复制代码
    void sendLogin(String username) throws JsonProcessingException;

2)UserServiceImpl.java增加sendLogin实现

复制代码
    @Autowired
    private WebServerEndpoint webServerEndpoint;
    @Override
    public void sendLogin(String username) throws JsonProcessingException{
        ObjectMapper mapper = new ObjectMapper();
        Map<String, Object> jsonMap = new HashMap<>();
        jsonMap.put("login_user", username);
        String info = mapper.writeValueAsString(jsonMap);
    
        webServerEndpoint.sendmsg(info);
    }

3)UserController.java登录函数中增加:

复制代码
    try {
    	userService.sendLogin(username);
    } catch (IOException e) {
        e.printStackTrace();
    }

3.ObjectMapper的作用

在我们的业务代码实现过程中,经常需要进行Java对象与JSON字符串之间的转换。ObjectMapper是Jackson库中的一个重要类,该类提供了将JSON数据与Java对象之间进行相互转换的功能。具体来说,该类能够完成以下两种转换操作:首先,该类能够将Java对象转换为JSON格式的字符串,这种操作便于数据的传输和存储;其次,该类还能够将JSON字符串转换为Java对象,这种操作则方便在代码中进行数据处理和操作。

三、前端代码实现

修改前端demo的App.vue文件,script中实现WebSocket客户端代码。

复制代码
    <script setup>
     // 客户端和服务器连接的地址(我们服务端监听的地址)
    let ws = new WebSocket("ws://localhost:8080/myWs")
    ws.onopen=function (){ // 连接打开的时候向服务器发送一条消息
        ws.send("hello")
    }
    ws.onmessage=function (message) {
        console.log(message.data) // 服务器返回的消息
    }
    </script>

四、postman调试

1)启动Spring Boot后端服务。
2)启动前端演示程序,并在浏览器中访问 localhost:5173。
后端Spring Boot服务通过WebSocket客户端接收到“hello”消息,并在日志中进行了记录。

在这里插入图片描述

前端demo收到“收到”消息,日志如下图:

在这里插入图片描述

3)postman发送login消息。

在这里插入图片描述

4)

4)

4)

在这里插入图片描述

前端demo收到admin登录事件,日志如下图:

在这里插入图片描述

总结

本文主要探讨Spring Boot集成WebSocket实现后端向端上报消息事件的技术方法。其中,WebSocket协议可作为HTTP协议的补充,以实现一些HTTP协议无法单独完成的业务功能。值得注意的是,WebSocket还可以作为一个独立的TCP协议通道进行通信,目前我们暂不深入研究,后续有机会会与大家分享相关应用。在下篇文章中,我们将深入解析Token的使用方法。

全部评论 (0)

还没有任何评论哟~