菜鳥新來,大神勿噴,些許醍醐,感激涕零。因為 我總是裝幽默,是因為我想讓自己快樂。
websocket為瀏覽器為服務器提供了雙工異步通信的功能,即瀏覽器可以向服務器發送消息,服務器也可以向瀏覽器發送消息。websocket需要瀏覽器的支持(ie10+、chrome 13+、firefox 6+)。
websocket是通過一個socket來實現雙工異步通信功能,但是直接使用websocket會比較麻煩,我們使用它的子協議stomp,它是一個更高級的協議,stomp使用一個基於幀的格式來定義消息,與http的request和response類似。
實戰(新建spring boot項目,選擇thymeleaf和websocket)
1、廣播式
廣播式即服務端有消息時,會將消息發給所有連接了當前endpoint的瀏覽器。
① 配置websocket,需要再配置類上使用@EnableWebSocketMessageBroker開啟websocket,並通過AbstractWebSocketMessageBrokerConfigurer類。
package com.example.demo; 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; import org.springframework.web.socket.config.annotation.WebSocketMessageBrokerConfigurer; /** * Created by xingzhuipingye on 2017/5/25. */ @Configuration //開啟stomp協議來傳輸基於代理message broker的消息 @EnableWebSocketMessageBroker public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer { @Override //注冊stomp協議節點 endpoint public void registerStompEndpoints(StompEndpointRegistry stompEndpointRegistry) { //注冊一個endpoint 並指定是喲個socketjs stompEndpointRegistry.addEndpoint("/endpointWisely").withSockJS(); } @Override //配置消息代理 public void configureMessageBroker(MessageBrokerRegistry registry) { //廣播式配置一個topic的消息代理 registry.enableSimpleBroker("/topic"); } }
② 瀏覽器向服務器發送的類
package com.example.demo; /** * Created by xingzhuipingye on 2017/5/25. */ //瀏覽器向服務器發送消息用此類接受 public class WiselyMessage { private String name; public String getName() { return name; } }
③ 服務器向瀏覽器發送此類的消息
package com.example.demo; /** * Created by xingzhuipingye on 2017/5/25. */ public class WiselyResponse { private String responseMessage; public WiselyResponse(String responseMessage) { this.responseMessage = responseMessage; } public String getResponseMessage() { return responseMessage; } }
④ 控制器
package com.example.demo; import org.springframework.messaging.handler.annotation.MessageMapping; import org.springframework.messaging.handler.annotation.SendTo; import org.springframework.stereotype.Controller; /** * Created by xingzhuipingye on 2017/5/25. */ @Controller public class WsController { //當瀏覽器向服務器發送請求的時候通過@MessageMapping 映射/welcome 這個地址 類似 RequestMapping @MessageMapping("/welcome") //當服務器有消息的時候,會對訂閱了@SendTo中的路徑瀏覽器發送消息 @SendTo("/topic/getResponse") public WiselyResponse say(WiselyMessage wiselyMessage) throws InterruptedException { Thread.sleep(3000); return new WiselyResponse("Welcome," + wiselyMessage.getName()); } }
⑤ 頁面
<!DOCTYPE html> <html lang="cn" xml:th="http://www.thymeleaf.org" xmlns:link="http://www.w3.org/1999/xhtml" xmlns:th="http://www.w3.org/1999/xhtml"> <head> <meta charset="UTF-8"/> <title>Title</title> <script src="http://cdn.bootcss.com/sockjs-client/1.1.4/sockjs.min.js"></script> <script src="https://cdn.bootcss.com/stomp.js/2.3.3/stomp.js"></script> <script src="https://cdn.bootcss.com/jquery/3.2.1/jquery.min.js"></script> </head> <body onload="disconnect()"> <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> </body> <script> 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'); stompClient = Stomp.over(socket); stompClient.connect({},function (frame) { setConnected(true); console.log('connected'+ frame); stompClient.subscribe('/topic/getResponse',function (response) { showResponse(JSON.parse(response.body).responseMessage); }); }); } function disconnect() { if(stompClient!=null){ stompClient.disconnect(); } setConnected(false); console.log('disconnected') } function sendName() { var name = $('#name').val(); stompClient.send('/welcome',{},JSON.stringify({'name':name})); } function showResponse(message) { var response = $('#response'); response.html(message); } </script> </html>
打開三個瀏覽器分別輸入名字測試
當一個瀏覽器發送一個消息到服務器端的時候,其他瀏覽器也能收到從服務器端發送來的消息。
點對點后續補充。。。