Skip to content

websocket的基础使用

在Web应用中,WebSocket提供了在单个长时间连接上进行全双工、双向通讯的能力(基于HTTP协议)。

它允许服务器主动向客户端发送信息,适合需要实时功能的应用,如在线聊天、实时通知、游戏等。

使用示例

添加依赖

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

相关配置

创建一个WebSocket配置类,使用@EnableWebSocket注解来启用WebSocket,并注册一个WebSocket端点

import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.config.annotation.EnableWebSocket;
import org.springframework.web.socket.config.annotation.WebSocketConfigurer;
import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry;

@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer {

    @Override
    public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
        registry.addHandler(myHandler(), "/myWebSocket").withSockJS();
    }

    public WebSocketHandler myHandler() {
        return new MyWebSocketHandler();
    }
}

前端操作,vue 项目(这里使用的是若 依 的框架)

先安装一下依赖

npm install sockjs-client webstomp-client --registry=https://registry.npmmirror.com

创建一个组件

<template>
  <div>
    <input v-model="messageToSend" placeholder="输入消息" />
    <button @click="sendMessage">发送消息</button>
    <div v-for="(msg, index) in messagesReceived" :key="index">
      {<!-- -->{ msg }}
    </div>
  </div>
</template>

<script>
import SockJS from 'sockjs-client';
import Stomp from 'webstomp-client';

export default {
  data() {
    return {
      stompClient: null,
      messageToSend: '',
      messagesReceived: [],
    };
  },
  mounted() {
    this.connect();
  },
  methods: {
    connect() {
      const socket = new SockJS('/myWebSocket');
      this.stompClient = Stomp.over(socket);
      this.stompClient.connect({}, frame => {
        console.log('Connected: ' + frame);
        this.stompClient.subscribe('/topic/messages', message => {
          this.messagesReceived.push(JSON.parse(message.body).content);
        });
      });
    },
    sendMessage() {
      if (this.stompClient && this.messageToSend) {
        const message = JSON.stringify({ content: this.messageToSend });
        this.stompClient.send('/app/message', {}, message);
        this.messageToSend = ''; // 清空输入框
      }
    }
  }
};
</script>

在这个组件中:

  • 使用v-model绑定一个文本输入框的值到messageToSend
  • 点击发送按钮时,调用sendMessage方法。
  • mounted钩子中,组件挂载后立即调用connect方法来连接WebSocket服务器。
  • connect方法使用SockJSStomp库建立连接,并订阅服务器上的消息。接收到的消息被添加到messagesReceived数组中,并在模板中遍历显示。
  • sendMessage方法通过WebSocket发送用户输入的消息到服务器。

确保服务器端WebSocket配置正确,且/myWebSocket端点以及/app/message/topic/messages目的地可用。这个示例假设服务器端能够接收客户端发送的消息,并能将消息广播到/topic/messages目的地

mounted是Vue组件的一个生命周期钩子,它在组件的模板和DOM已经渲染完毕并挂载到页面上之后被调用。这个时刻,组件已经出现在页面上,任何对DOM的操作都可以在这个钩子中执行。

在这个WebSocket示例中,mounted钩子用来在组件挂载完成后立即建立WebSocket连接,这样做确保了一旦组件准备好,就可以开始接收来自服务器的消息。

  • /myWebSocket:是WebSocket连接的端点,客户端通过这个URL与服务器建立WebSocket连接。
  • /topic/messages:是服务器上一个消息主题,客户端通过订阅这个主题来接收服务器广播的消息

建议单独搞一个前端界面作为演示,可以参考一下这个,如果是做聊天室之类的,可以用这种方式:

后面测试调整了一下:

首先是前端组件引用:

<el-form-item label="websocket" prop="websocket">
  <web-socket-component></web-socket-component>
</el-form-item>

import WebSocketComponent from '@/components/Luoqi/websocket/index.vue';

components: { 
  Treeselect, 
  WebSocketComponent
},

连接地址改了一下

const socket = new SockJS('http://localhost:8080/myWebSocket');

后端的一些跨域和访问权限放行的配置需要改一下

SecurityConfig 配置类下 的 configure 方法

#这里改匿名访问也可以
.antMatchers("/myWebSocket/**").permitAll()

WebSocketConfig 配置类,需要添加一下 setAllowedOrigins 配置

public class WebSocketConfig implements WebSocketConfigurer {  
  
  
    @Override  
    public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {  
        registry.addHandler(myHandler(), "/myWebSocket")  
                .setAllowedOrigins("http://localhost")  
                .withSockJS();  
    }  
  
    public WebSocketHandler myHandler() {  
        return new MyWebSocketHandler();  
    }  
  
  
    //开启 WebSocket的支持  
    @Bean  
    public ServerEndpointExporter serverEndpointExporter(){  
        return  new ServerEndpointExporter();  
    }  
}

同时在若依分离式项目中,尽量都 clean 再 install 一下

聊天室

这个是比较常见的功能,可以尝试一下实现。

基础用法

看一下这个: https://mp.weixin.qq.com/s/0SI9C3tBPqyIeMtkfTZk8g

Netty + WebSocket

参考: https://github.com/niezhiliang/netty-websocket-spring-boot