SpringBoot 集成 WebSocket 简单模拟群发通知

前言

早期,很多网站为了实现推送技术,所用的技术都是轮询。轮询是指由浏览器每隔一段时间(如每秒)向服务器发出HTTP请求,然后服务器返回最新的数据给客户端。这种传统的模式带来很明显的缺点,即浏览器需要不断的向服务器发出请求,然而HTTP请求与回复可能会包含较长的头部,其中真正有效的数据可能只是很小的一部分,所以这样会消耗很多带宽资源。比较新的轮询技术是Comet。这种技术虽然可以实现双向通信,但仍然需要反复发出请求。而且在Comet中普遍采用的HTTP长连接也会消耗服务器资源。在这种情况下,HTML5定义了WebSocket协议,在WebSocket API中,浏览器和服务器只需要完成一次握手,两者之间就可以创建持久性的连接,并进行双向数据传输,这样能更好的节省服务器资源和带宽,并且能够更实时地进行通讯(以上内容来自维基百科)。

Websocket使用wswss的统一资源标志符(URI)。其中wss表示使用了TLSWebsocket。如:

ws://example.com/wsapi
wss://secure.example.com/wsapi

下面就通过一个简单的例子介绍如何在SpringBoot中集成WebSocket,只展示WebSocket的核心配置,完整代码已上传到GitHub(由于下篇博客对本文的代码有改造,在测试的时候需要输入 https://localhost 而不是 http://localhost:8080,同时本地需要先创建一个 blog 数据库和 user 表并添加测试数据):

效果展示

在展示代码配置前,先展示一下效果(已提前登录了三个用户):

SpringBoot 集成 WebSocket 简单模拟群发通知_第1张图片

具体的代码配置

  1. 引入依赖

    首先需要在pom.xml中引入以下依赖:

    <dependency>
    	<groupId>org.springframework.bootgroupId>
    	<artifactId>spring-boot-starter-websocketartifactId>
    dependency>
    
  2. 配置ServerEndpointExporterBean

    @Configuration
    public class WebSocketConfig {
    
        @Bean
        public ServerEndpointExporter serverEndpointExporter(){
            return new ServerEndpointExporter();
        }
    }
    
  3. 配置服务器终端

    @Component
    @ServerEndpoint("/websocket")
    public class WebSocketServer {
    
        private Session session;
        // 保存所有的客户端连接
        private static final Map<String, WebSocketServer> connections = new LinkedHashMap<>();
    
        @OnOpen
        public void onOpen(Session session) {
            this.session = session;
            connections.put(session.getId(), this);
        }
    
        @OnMessage
        public void onMessage(String message, Session session) {
            try {
                sendMessage(message);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
        @OnError
        public void onError(Throwable error, Session session) throws Throwable {
            throw error;
        }
    
        @OnClose
        public void onClose() {
            connections.remove(session.getId());
        }
    
        public void sendMessage(String message) throws IOException {
            session.getBasicRemote().sendText(message);
        }
    
        // 广播方法(实现消息群发)
        public static void broadcast(String message) {
            connections.forEach((k, v) -> {
                try {
                    v.sendMessage(message);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            });
        }
    }
    
  4. 配置群发通知接口

    @RestController
    public class BroadcastController {
    
        @PostMapping("/broadcast")
        public void broadcast(@RequestBody String msg){
            WebSocketServer.broadcast(msg);
        }
    }
    
  5. 客户端配置

    客户端简单使用Vue框架,没有使用单文件组件形式,客户端连接代码如下:

    let socket = new WebSocket("ws://localhost:8080/websocket")
    socket.onerror = err => {
        console.log(err)
    }
    
    socket.onopen = event => {
        console.log(event)
    }
    
    socket.onmessage = event => {
        // 这里接受服务端发送的信息
        vue.$data.toast = {
            isShow: true,
            msg: JSON.parse(event.data).msg
        }
    }
    
    socket.onclose = () => {
        console.log("连接关闭")
    }
    

    完成以上简单配置后,只要调用了群发信息的接口,客户端就可以通过onmessage函数来处理接收到的信息。

  6. 浏览器控制台测试

    如果想要尽快测试结果,不想写前端代码,可以直接在控制台中输入以下代码(对5中的代码稍作修改):

SpringBoot 集成 WebSocket 简单模拟群发通知_第2张图片

然后在新建一个页面并地址栏中输入http://localhost:8080/broadcast?msg=1234567并回车(记得将4中的PostMapping改为GetMapping,并删掉@RequestBody),输完回车后,在返回上一个界面查看控制台,即可发现接收信息:

SpringBoot 集成 WebSocket 简单模拟群发通知_第3张图片

总结

本文简单介绍了如何通过SpringBoot集成WebSocket实现群发信息的功能,本文只讲解了WebSocket的基本使用,也只使用了ws,在下篇文章将会介绍如何使用加密的wss协议。

你可能感兴趣的:(Java,HTTP,java,websocket,spring,boot,vue,http)