WebSocket是客戶端和服務端的通信(https://www.cnblogs.com/jingmoxukong/p/7755643.html)
了解計算機網絡協議的人,應該都知道:HTTP 協議是一種無狀態的、無連接的、單向的應用層協議。它采用了請求/響應模型。通信請求只能由客戶端發起,服務端對請求做出應答處理。
這種通信模型有一個弊端:HTTP 協議無法實現服務器主動向客戶端發起消息。
這種單向請求的特點,注定了如果服務器有連續的狀態變化,客戶端要獲知就非常麻煩。大多數 Web 應用程序將通過頻繁的異步JavaScript和XML(AJAX)請求實現長輪詢。輪詢的效率低,非常浪費資源(因為必須不停連接,或者 HTTP 連接始終打開)。
因此,工程師們一直在思考,有沒有更好的方法。WebSocket 就是這樣發明的。WebSocket 連接允許客戶端和服務器之間進行全雙工通信,以便任一方都可以通過建立的連接將數據推送到另一端。WebSocket 只需要建立一次連接,就可以一直保持連接狀態。這相比於輪詢方式的不停建立連接顯然效率要大大提高。
Web瀏覽器和服務器都必須實現 WebSockets 協議來建立和維護連接。由於 WebSockets 連接長期存在,與典型的HTTP連接不同,對服務器有重要的影響。
基於多線程或多進程的服務器無法適用於 WebSockets,因為它旨在打開連接,盡可能快地處理請求,然后關閉連接。任何實際的 WebSockets 服務器端實現都需要一個異步服務器。
一、前端代碼(order-->list.ftl)
<#--播放音樂-->
<audio id="notice" loop="loop">
<source src="/sell/mp3/song.mp3" type="audio/mpeg" />
</audio>
<script src="https://cdn.bootcss.com/jquery/1.12.4/jquery.min.js"></script>
<script src="https://cdn.bootcss.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
<script>
var websocket = null;
if('WebSocket' in window) {
websocket = new WebSocket('ws://sell.natapp4.cc/sell/webSocket');
}else {
alert('該瀏覽器不支持websocket!');
}
websocket.onopen = function (event) {
console.log('建立連接');
}
websocket.onclose = function (event) {
console.log('連接關閉');
}
websocket.onmessage = function (event) {
console.log('收到消息:' + event.data)
//彈窗提醒, 播放音樂
$('#myModal').modal('show');
document.getElementById('notice').play();
}
websocket.onerror = function () {
alert('websocket通信發生錯誤!');
}
window.onbeforeunload = function () {
websocket.close();
}
</script>
二、先在后端pom.xml引進
三、做配置類WebSocketConfig
四、編寫WebSocket類(https://blog.csdn.net/zzhao114/article/details/60154017)
package com.imooc.service;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import javax.websocket.OnClose;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;
import java.util.concurrent.CopyOnWriteArraySet;
@Component
@ServerEndpoint("/webSocket")
@Slf4j
public class WebSocket {
private Session session;
private static CopyOnWriteArraySet<WebSocket> webSocketSet = new CopyOnWriteArraySet<>(); //儲存session
@OnOpen
public void onOpen(Session session) {
this.session = session;
webSocketSet.add(this);
log.info("【websocket消息】有新的連接, 總數:{}", webSocketSet.size());
}
@OnClose
public void onClose() {
webSocketSet.remove(this);
log.info("【websocket消息】連接斷開, 總數:{}", webSocketSet.size());
}
@OnMessage
public void onMessage(String message) {
log.info("【websocket消息】收到客戶端發來的消息:{}", message);
}
public void sendMessage(String message) {
for (WebSocket webSocket: webSocketSet) {
log.info("【websocket消息】廣播消息, message={}", message);
try {
webSocket.session.getBasicRemote().sendText(message);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
發送消息只需要使用websocket.send("發送消息"),就可以觸發服務端的onMessage()方法,當連接時,觸發服務器端onOpen()方法,此時也可以調用發送消息的方法去發送消息。關閉websocket時,觸發服務器端onclose()方法,此時也可以發送消息,但是不能發送給自己,因為自己的已經關閉了連接,但是可以發送給其他人。
五、在創建新訂單時發送消息