菜鳥新來,大神勿噴,些許醍醐,感激涕零。因為 我總是裝幽默,是因為我想讓自己快樂。
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>
打開三個瀏覽器分別輸入名字測試

當一個瀏覽器發送一個消息到服務器端的時候,其他瀏覽器也能收到從服務器端發送來的消息。
點對點后續補充。。。
