springboot2 -廣播式WebSocket


1.WebSocket,STOMP,SockJS含義

WebSocket:WebSocket是HTML5開始提供的一種在單個 TCP 連接上進行全雙工通訊的協議。

SockJS:SockJS 是 WebSocket 技術的一種模擬。為了應對許多瀏覽器不支持WebSocket協議的問題,設計了備選SockJs。開啟並使SockJS后,它會優先選用Websocket協議作為傳輸協議,如果瀏覽器不支持Websocket協議,則會在其他方案中,選擇一個較好的協議進行通訊。

STOMP:用於定義websocket的消息體格式.

2.springboot代碼

定義websocket傳輸消息的內容格式。

瀏覽器向服務端發送消息:

package com.dyq.demo.DTO;

public class SocketRequestMessage {
    private String requestMessage;

    public String getRequestMessage() {
        return requestMessage;
    }
}

服務端向瀏覽器發送消息:

package com.dyq.demo.DTO;

public class SocketResponseMessage {
    private String responseMessage;

    public SocketResponseMessage(String responseMessage){
        this.responseMessage = responseMessage;
    }

    public String getResponseMessage() {
        return responseMessage;
    }
}

WebSocket配置文件:

package com.dyq.demo.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.messaging.simp.config.MessageBrokerRegistry;
import org.springframework.web.socket.config.annotation.*;


@Configuration
@EnableWebSocketMessageBroker//啟用STOMP協議來傳輸基於代理(message broker)的消息
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
        //注冊一個stomp的節點,使用SockJS協議
        registry.addEndpoint("/customendpoint").withSockJS();
    }

    @Override
    public void configureMessageBroker(MessageBrokerRegistry config) {
        //config.setApplicationDestinationPrefixes("/app");
        //使用內置的消息代理進行訂閱和廣播;路由消息的目標頭以“/topic”或“/queue”開頭。
        config.enableSimpleBroker("/topic", "/queue");
    }
}

控制器代碼:

package com.dyq.demo.controller;

import com.dyq.demo.DTO.SocketRequestMessage;
import com.dyq.demo.DTO.SocketResponseMessage;
import org.springframework.messaging.handler.annotation.MessageMapping;
import org.springframework.messaging.handler.annotation.SendTo;
import org.springframework.stereotype.Controller;

@Controller
public class WebSocketController {
    @MessageMapping("/socket")//瀏覽器向服務器發送請求時,通過MessageMapping映射/socket地址
    @SendTo("/topic/getResponse")//當服務器有消息時,會對訂閱了@SendTo中路徑的瀏覽器發送消息
    public SocketResponseMessage say(SocketRequestMessage message) throws InterruptedException {
        Thread.sleep(3000);
        return new SocketResponseMessage("接收到RequestMessage:"+message.getRequestMessage()+"!");
    }
}

前端頁面代碼websocket.html:
前端需要三個js文件,大家可以到http://www.bootcdn.cn/去搜索下載
目前最新版:
sockjs.min.js:https://cdn.bootcss.com/sockjs-client/1.1.4/sockjs.min.js
stomp.min.js:https://cdn.bootcss.com/stomp.js/2.3.3/stomp.min.js
jquery.min.js:https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>websocket</title>
</head>
<body>
    <noscript>Your browser does not support JavaScript!</noscript>
    <div>
        <div>
            <button id="connect" onclick="connect()">連接</button>
            <button id="disconnect" onclick="disconnect()">斷開連接</button><br/>
            <p id="connectStatus">未連接</p>
            <br/><br/>
        </div>
        <div id="conversation">
            <label>輸入發送信息</label>
            <input type="text" id="requestMessage">
            <button id="sendMessage" onclick="sendMessage()">發送</button>
            <p id="responseMessage"></p>
        </div>
    </div>
    <script th:src="@{js/sockjs.min.js}"></script>
    <script th:src="@{js/stomp.min.js}"></script>
    <script th:src="@{js/jquery.min.js}"></script>
    <script type="text/javascript">
        var stompClient = null;
        $(function () {
            setConnected(false);
        });
        function setConnected(connected) {
            if(connected){
                $("#connect").attr("disabled",true);
                $("#disconnect").attr("disabled",false);
                $("#conversation").show();
                $("#connectStatus").html("已連接");
            }else{
                $("#connect").attr("disabled",false);
                $("#disconnect").attr("disabled",true);
                $("#conversation").hide();
                $("#connectStatus").html("未連接");
            }
            $("#responseMessage").html();
        }
        function connect() {
            var socket = new SockJS("/customendpoint");//連接SockJs的endpoint-/customendpoint
            stompClient = Stomp.over(socket)//使用STOMP子協議的WebSocket客戶端
            stompClient.connect({},function (frame) {
                setConnected(true);
                console.log("Connected:"+frame);
                stompClient.subscribe("/topic/getResponse",function (response) {
                    showResponseMessage(JSON.parse(response.body).responseMessage);
                });
            });
        }
        function disconnect() {
            if(stompClient!=null){
                stompClient.disconnect();
                setConnected(false);
                console.log("Disconnected")
            }
        }
        function showResponseMessage(message) {
            $("#responseMessage").html(message);
        }
        function sendMessage() {
            var requseMessage = $("#requestMessage").val();
            console.log("requseMessage:"+requseMessage);
            stompClient.send("/socket",{},JSON.stringify({"requestMessage":requseMessage}));
        }
    </script>
</body>
</html>

需要在Mvc配置文件:

package com.dyq.demo.config;


import org.apache.catalina.Context;
import org.apache.catalina.connector.Connector;
import org.apache.tomcat.util.descriptor.web.SecurityCollection;
import org.apache.tomcat.util.descriptor.web.SecurityConstraint;
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
import org.springframework.boot.web.servlet.server.ServletWebServerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.*;


@Configuration
public class MVCConfig implements WebMvcConfigurer {

    public void addViewControllers(ViewControllerRegistry registry) {
        registry.addViewController("/").setViewName("/index");
        registry.addViewController("/index").setViewName("/index");
        registry.addViewController("/websocket").setViewName("/websocket");
    }
}

運行,開多個瀏覽器窗口,連接上,如果一個瀏覽器發送消息到服務器,其他窗口能接受到信息。
然后運行效果:


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM