SpringBoot+vue实现WebSocket通信

发布于:2024-12-19 ⋅ 阅读:(141) ⋅ 点赞:(0)

WebSocket是一种在单个TCP连接上进行全双工通信的协议。WebSocket使得客户端和服务器之间的数据交换变得更加简单,允许服务器主动向客户端推送数据。

WebSocket的主要特点:

  1. 全双工通信:客户端和服务器之间的数据可以同时双向传输
  2. 低延迟:由于是持久连接,所以不需要每次通信都重新建立连接,这大大减少了延迟。
  3. 节省带宽:WebSocket只需要一次握手,后续的数据传输都是基于这个连接,因此相对HTTP轮询来说更加节省带宽。

WebSocket的基本使用流程:

  1. 客户端发起请求:客户端发起一个WebSocket请求到服务器
  2. 握手阶段:服务器同意请求后,双方进入全双工模式。
  3. 数据传输:客户端和服务器客厅通过send()方法发送数据,通过onmessage事件处理接收到的数据。
  4. 关闭连接:当不再需要通信时,可以调用close()方法关闭连接。

 服务器(SpringBoot)示例代码

依赖引入

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

WebSocket配置类

@Configuration
public class WebSocketConfig {

    @Bean
    public ServerEndpointExporter serverEndpoint() {
        return new ServerEndpointExporter();
    }

}

业务处理类

@Slf4j
@Component
@ServerEndpoint("/websocket/{username}")
public class WebSocketTest {

    private Session session;

    private String username;

    private static ConcurrentHashMap<String, WebSocketTest> webSocketSet = new ConcurrentHashMap<>();

    @OnOpen
    public void onOpen(Session session, @PathParam("username") String username) {
        // 新的连接建立时执行,并且记录用户名
        this.session = session;
        this.username = username;
        webSocketSet.put(username, this);
    }

    @OnMessage
    public void onMessage(String message, Session session) {
        // 接收到前端消息时执行
        System.out.println("Received: " + message);
        try {
            session.getBasicRemote().sendText("Response from server: " + message);
        } catch (IOException e) {
            {
                e.printStackTrace();
            }
        }
    }

        @OnClose
        public void onClose (Session session, CloseReason closeReason){
            webSocketSet.remove(this.username);
        }

        @OnError
        public void onError (Session session, Throwable throwable){
            // 发生错误时执行
            System.out.println("Error ... " + session.getId());
            throwable.printStackTrace();
        }

    public void sendMessage2User(String message,String username) {
        try {
            webSocketSet.get(username).session.getBasicRemote().sendText(message);
        } catch (IOException e) {
            log.error("method=sendMessage2User||msg=send msg to user error", e);
        }
    }

    public void sendMessage() {
        String filePath = "C:/Users/heal/Desktop/1.txt"; // 替换为你的文件路径

        try (BufferedReader br = new BufferedReader(new FileReader(filePath))) {
            String line;
            while ((line = br.readLine()) != null) {
                // username需要从客户端传入,我这里只是测试,所以写死
                sendMessage2User(line,"admin");
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

服务器记录每次连接的用户名,用于每次发送请求的session认证 

客户端(vue)调用代码示例

import Vue from 'vue'

const WebSocketPlugin = {
  install(Vue, options) {
    const ws = new WebSocket('wss://127.0.0.1:8443/webserver/websocket')

    Vue.prototype.$websocket = {
      send(message) {
        if (ws.readyState === WebSocket.OPEN) {
          ws.send(message)
        }
      },
      onMessage(callback) {
        ws.onmessage = callback
      },
      onOpen(callback) {
        ws.onopen = callback
      },
      onClose(callback) {
        ws.onclose = callback
      },
      onError(callback) {
        ws.onerror = callback
      }
    }

    Vue.mixin({
      created() {
        if (this.$options.websocket) {
          this.$websocket.onMessage((message) => {
            // 处理接收到的消息
            console.log(message)
          })
        }
      }
    })
  }
}

export default WebSocketPlugin

send() {
      this.$websocket.send('Hello, WebSocket!')
    },

也可以使用apifox直接发请求到服务器

这样就吧文件中的内容实时的返回给客户端了