WebSocket 實現先後端通訊的筆記

以前在作站內信時,用到了 WebSocket ,整理了一些筆記分享以下。
本文基於 SpringBoot 2.1.5,本文不涉及環境搭建。javascript

引入依賴

在 Spring 中要使用 WebSocket 功能,須要在pom中引入依賴:css

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

配置類

增長一個配置類,用於定義 WebSocket 全局配置信息html

@Configuration
@EnableWebSocketMessageBroker
public class WebSocketStompConfig implements WebSocketMessageBrokerConfigurer {

    /**
     * 註冊stomp端點
     * @param registry
     */

    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {

        ## 容許使用socketJs方式訪問 便可經過http://IP:PORT/xboot/ws來和服務端websocket鏈接
        registry.addEndpoint("/tmax/ws").setAllowedOrigins("*").withSockJS();
    }

    /**
     * 配置信息代理
     * @param registry
     */

    @Override
    public void configureMessageBroker(MessageBrokerRegistry registry) {

        ## 訂閱Broker名稱 user點對點 topic廣播即羣發
        registry.enableSimpleBroker("/user","/topic");
        ## 全局(客戶端)使用的消息前綴
        registry.setApplicationDestinationPrefixes("/app");
        ## 點對點使用的前綴 無需配置 默認/user
        registry.setUserDestinationPrefix("/user");
    }
}

來看一下這兩個方法:java

一、registerStompEndpoints(StompEndpointRegistry registry)

註冊stomp端點。起到的做用就是添加一個服務端點,來接收客戶端的鏈接,
registry.addEndpoint("/tmax/ws") 表示添加了一個 /tmax/ws 端點,客戶端能夠經過這個端點來進行鏈接。withSockJS() 的做用是開啓 SockJS 訪問支持,便可經過http://IP:PORT/tmax/ws 來和服務端 websocket 鏈接。jquery

二、configureMessageBroker(MessageBrokerRegistry registry)

配置信息代理。定義消息代理,設置消息鏈接請求的各類規範信息。
registry.enableSimpleBroker("/user","/topic") 表示客戶端訂閱地址的前綴信息,也就是客戶端接收服務端消息的地址的前綴信息(比較繞,看完整個例子,大概就能明白了)registry.setApplicationDestinationPrefixes("/app") 指服務端接收地址的前綴,意思就是說客戶端給服務端發消息的地址的前綴。
registry.setUserDestinationPrefix("/user") 指推送用戶前綴。web

我不不難發現,setApplicationDestinationPrefixessetUserDestinationPrefix 起到的效果敲好相反,一個定義了客戶端接收的地址前綴,一個定義了客戶端發送地址的前綴。ajax

開始業務代碼的編寫

先了解幾個知識點,下方會用到。spring

一、MessageMapping

接收客戶端請求鏈接註解。Spring 對於 WebSocket 封裝的特別簡單,提供了一個 @MessageMapping 註解,功能相似 @RequestMapping,它是存在於Controller中的,定義一個消息的基本請求,功能也跟 @RequestMapping相似,包括支持通配符 的url定義等等。後端

二、SimpMessagingTemplate

SimpMessagingTemplate 是 Spring-WebSocket 內置的一個消息發送工具,能夠將消息發送到指定的客戶端。api

三、SendTo

@SendTo 能夠把消息廣播到路徑上去,例以下面能夠把消息廣播到 "/topic/greetings」,若是客戶端在這個路徑訂閱消息,則能夠接收到消息

接下來看一下後臺代碼實現,HelloController

/**
 * @author niceyoo
 */

@Slf4j
@Controller
@Api(description = "hello接口")
@Transactional
public class HelloController {

    @Autowired
    private SimpMessagingTemplate messagingTemplate;

    /**
     * 跳轉至hello.html界面
     * @return
     */

    @RequestMapping("/hello")
    public String hello(){
        return "hello";
    }

    /**
     * 接收而後轉發至客戶端消息
     * @param message
     * @return
     * @throws Exception
     */

    @MessageMapping("/top")
    @SendTo("/topic/greetings")
    public String greeting(String message) throws Exception {
        System.out.println("receiving " + message);
        System.out.println("connecting successfully.");
        return "AAA:"+message;
    }

    /**
     * 推送消息
     * @return
     */

    @ResponseBody
    @RequestMapping("/hello/addMessage")
    public Result<Object> addMessage(){
        messagingTemplate.convertAndSend("/topic/greetings""您收到了新的系統消息");
        return new ResultUtil<Object>().setSuccessMsg("添加成功");
    }

}

hello.html 代碼:

<!doctype html>
<html>
<head>
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
    <script src="https://cdn.bootcss.com/sockjs-client/1.3.0/sockjs.js"></script>
    <script src="https://cdn.bootcss.com/stomp.js/2.3.3/stomp.js"></script>
    <style>
        .box {
            width: 300px;
            float: left;
            margin: 0 20px 0 20px;
        }
        .box div, .box input {
            border: 1px solid;
            -moz-border-radius: 4px;
            border-radius: 4px;
            width: 100%;
            padding: 0px;
            margin: 5px;
        }
        .box div {
            border-color: grey;
            height: 300px;
            overflow: auto;
        }
        .box input {
            height: 30px;
        }
        h1 {
            margin-left: 30px;
        }
        body {
            background-color: #F0F0F0;
            font-family: "Arial";
        }
    </style>
</head>
<body lang="en">
<h1>Index</h1>
<div id="first" class="box">
    <div></div>
    <input autocomplete="off" value="Type here..."></input>
    <button onclick="connect()">登錄客戶端</button>
    <button onclick="send()">發送消息</button>
</div>
<script>
    var stompClient = null;
    var sockjs_url = '/tmax/ws';

    function connect() {
        var sockjs = new SockJS(sockjs_url);
        stompClient = Stomp.over(sockjs);
        stompClient.connect({}, function(frame) {
            console.log('Connected: ' + frame);
            stompClient.subscribe('/topic/greetings', function(greeting){
                console.log("返回內容:"+greeting.body);
                print('服務器:', greeting.body);
            });
        });
    }

    function send() {
        if(stompClient == null){
            print('系統提示:', '請先點擊客戶端登錄');
            return false;
        }
        print('客戶端:', inp.val());
        stompClient.send("/app/top", {}, inp.val());
        inp.val('');
    }

    $('#first input').focus();
    var div  = $('#first div');
    var inp  = $('#first input');

    var print = function(m, p) {
        p = (p === undefined) ? '' : p;
        div.append($("<code>").text(m + ' ' + p));
        div.append($("<br>"));
        div.scrollTop(div.scrollTop()+10000);
    };

</script>
</body>
</html>

操做流程:

點擊「登陸客戶端」,輸入框內輸入內容,點擊發送消息。

消息推送

關於消息的推送,藉助 postman,調用 http://127.0.0.1:8888/hello/addMessage,實現後端推送至客戶端。

額外補充,關於消息推送,每每會用到推送至指定用戶,則:messagingTemplate.convertAndSendToUser(id,"/queue/subscribe", "您收到了新的消息"); ,其中id爲系統用戶id。

詳細可搜索 SimpMessagingTemplate 的一些用法。

若是文章有錯的地方歡迎指正,你們互相留言交流。習慣在微信看技術文章,想要獲取更多的Java資源的同窗,能夠關注微信公衆號:niceyoo

參考地址:https://www.jianshu.com/p/60799f1356c5

相關文章
相關標籤/搜索