zoukankan      html  css  js  c++  java
  • SpringBoot 整合 WebSocket

    SpringBoot 整合 WebSocket(topic广播)

    1、什么是WebSocket

      WebSocket为游览器和服务器提供了双工异步通信的功能,即游览器可以向服务器发送消息,服务器也可以向游览器发送消息。WebSocket需游览器的支持,如IE10、Chrome 13+、Firefox 6+,这对我们现在的游览器来说都不是问题。

      WebSocket是通过一个socket来实现双工异步通讯能力的。但是直接使用WebSocket(或SockJS:WebSocket协议的模拟,增加了当游览器不支持WebSocket的时候的兼容支持)协议开发程序显得特别繁琐, 我们会使用它的子协议STOMP,它是一个更高级别的协议,STOMP协议使用一个基于帧的格式来定义消息,与HTTP的request和reponse类似(具有类似于@RequestMapping的@MassageMapping)

    2、什么是STOMP

      STOMP,Streaming Text Orientated Message Protocol,是流文本定向消息协议,是一种为MOM(Message Oriented Middleware,面向消息的中间件)设计的简单文本协议。
    它提供了一个可互操作的连接格式,允许STOMP客户端与任意STOMP消息代理(Broker)进行交互,类似于OpenWire(一种二进制协议)。由于其设计简单,很容易开发客户端,因此在多种语言和多种平台上得到广泛应用。其中最流行的STOMP消息代理是Apache ActiveMQ。

      STOMP协议工作于TCP协议之上,使用了下列命令:
          1)、SEND 发送
          2)、SUBSCRIBE 订阅
          3)、UNSUBSCRIBE 退订
          4)、BEGIN 开始
          5)、COMMIT 提交
          6)、ABORT 取消
          7)、ACK 确认
          8)、DISCONNECT 断开

    3、为什么需要WebSocket

      答案很简单,因为 HTTP 协议有一个缺陷:通信只能由客户端发起。
    举例来说,我们想了解今天的天气,只能是客户端向服务器发出请求,服务器返回查询结果。HTTP 协议做不到服务器主动向客户端推送信息。如果想持续从服务的获取消息,则只能使用轮询或建立长连接的方法来实现,但是这样或浪费很多不必要的资源。
    而webSocket则解决了这个问题,通信可由双方发起,只需要建立一次连接,服务的端就可以持续从服务端获得消息。主要用来做消息通知,消息推送等模块

    4、SpringBoot使用 STOMP 消息步骤

      1)、添加pom文件依赖

      2)、java方式配置websocket stomp

      3)、消息实体类

      4)、书写控制层

      5)、书写页面

    5、Pom 依赖

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

    6、java方式配置websocket stomp

    package com.example.demo.config;
    
    import org.springframework.context.annotation.Configuration;
    import org.springframework.messaging.simp.config.MessageBrokerRegistry;
    import org.springframework.web.socket.config.annotation.AbstractWebSocketMessageBrokerConfigurer;
    import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker;
    import org.springframework.web.socket.config.annotation.StompEndpointRegistry;
    
    @Configuration
    @EnableWebSocketMessageBroker
    public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer {
    
        /**
         * 配置链接端点
         * @param registry
         */
        @Override
        public void registerStompEndpoints(StompEndpointRegistry registry){
            registry.addEndpoint("/endpointWisely").withSockJS();
        }
    
        /**
         * 配置消息代理
         * @param registry
         */
        @Override
        public void configureMessageBroker(MessageBrokerRegistry registry){
            registry.enableSimpleBroker("/topic");
        }
    }
    

    7、消息实体类

    package com.example.demo.PoJo;
    
    /**
     * 消息接受
     */
    public class WiselyMessage {
    
        private String name;
    
        public String getName(){
            return name;
        }
    }
    package com.example.demo.PoJo;
    
    /**
     * 消息返回
     */
    public class WiselyResponse {
    
        private String responseMessage;
    
        public WiselyResponse(String responseMessage){
            this.responseMessage = responseMessage;
        }
    
        public String getResponseMessage(){
            return responseMessage;
        }
    
    }

    8、书写控制层

    package com.example.demo.controller;
    
    import com.example.demo.PoJo.WiselyMessage;
    import com.example.demo.PoJo.WiselyResponse;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.messaging.handler.annotation.MessageMapping;
    import org.springframework.messaging.handler.annotation.SendTo;
    import org.springframework.messaging.simp.SimpMessagingTemplate;
    import org.springframework.stereotype.Controller;
    
    import java.security.Principal;
    
    @Controller
    public class WsController {
    
        /**
         * MessageMapping 类似于 RequestMapping
         * SendTo 订阅地址 类似于 订阅一个URL (我的理解就是 调用了这个方法 在返回的时候会给订阅该url的地址发送数据)
         * @param message
         * @return
         * @throws Exception
         */
        @MessageMapping("/welcome")
        @SendTo("/topic/getResponse")
        public WiselyResponse say(WiselyMessage message) throws Exception {
            Thread.sleep(3000);
            return new WiselyResponse("Welcome," + message.getName() + "!");
        }
    }

    9、书写页面

    <!DOCTYPE html>
    <html xmlns:th="http://www.thymeleaf.org">
    <head>
        <meta charset="UTF-8" />
        <title>Spring Boot+WebSocket+广播式</title>
    
    </head>
    <body onload="disconnect()">
    <noscript><h2 style="color: #ff0000">貌似你的浏览器不支持websocket</h2></noscript>
    <div>
        <div>
            <button id="connect" onclick="connect();">连接</button>
            <button id="disconnect" disabled="disabled" onclick="disconnect();">断开连接</button>
        </div>
        <div id="conversationDiv">
            <label>输入你的名字</label><input type="text" id="name" />
            <button id="sendName" onclick="sendName();">发送</button>
            <p id="response"></p>
        </div>
    </div>
    <script th:src="@{sockjs.min.js}"></script>
    <script th:src="@{stomp.min.js}"></script>
    <script th:src="@{jquery.js}"></script>
    <script type="text/javascript">
        var stompClient = null;
    
        function setConnected(connected) {
            document.getElementById('connect').disabled = connected;
            document.getElementById('disconnect').disabled = !connected;
            document.getElementById('conversationDiv').style.visibility = connected ? 'visible' : 'hidden';
            $('#response').html();
        }
        
        function connect() {
            var socket = new SockJS('/endpointWisely'); //1
            stompClient = Stomp.over(socket);
            stompClient.connect({}, function(frame) {
                setConnected(true);
                console.log('Connected: ' + frame);
                stompClient.subscribe('/topic/getResponse', function(respnose){ //2
                    showResponse(JSON.parse(respnose.body).responseMessage);
                });
            });
        }
        
        
        function disconnect() {
            if (stompClient != null) {
                stompClient.disconnect();
            }
            setConnected(false);
            console.log("Disconnected");
        }
    
        function sendName() {
            var name = $('#name').val();
               //3
            stompClient.send("/welcome", {}, JSON.stringify({ 'name': name }));
        }
    
        function showResponse(message) {
              var response = $("#response");
              response.html(message);
        }
    </script>
    </body>
    </html>

    10、客户端发送和接收消息图解

  • 相关阅读:
    USACO 6.4 章节
    USACO 6.3 章节 你对搜索和剪枝一无所知QAQ
    USACO 6.1 章节
    USACO 5.5 章节
    USACO 5.4 章节
    USACO 5.3 章节
    99乘法表
    mini整数计算器
    python爬虫-爬取天气预报内容
    python实时监控服务器性能
  • 原文地址:https://www.cnblogs.com/yi1036943655/p/10089100.html
Copyright © 2011-2022 走看看