WebSocket的使用(基於VUE與SpringBoot)
阿新 • • 發佈:2018-12-14
WebSocket 是 HTML5 開始提供的一種在單個 TCP 連線上進行全雙工通訊的協議。
WebSocket 使得客戶端和伺服器之間的資料交換變得更加簡單,允許服務端主動向客戶端推送資料。在 WebSocket API 中,瀏覽器和伺服器只需要完成一次握手,兩者之間就直接可以建立永續性的連線,並進行雙向資料傳輸。
在 WebSocket API 中,瀏覽器和伺服器只需要做一個握手的動作,然後,瀏覽器和伺服器之間就形成了一條快速通道。兩者之間就直接可以資料互相傳送。
現在,很多網站為了實現推送技術,所用的技術都是 Ajax 輪詢。輪詢是在特定的的時間間隔(如每1秒),由瀏覽器對伺服器發出HTTP請求,然後由伺服器返回最新的資料給客戶端的瀏覽器。這種傳統的模式帶來很明顯的缺點,即瀏覽器需要不斷的向伺服器發出請求,然而HTTP請求可能包含較長的頭部,其中真正有效的資料可能只是很小的一部分,顯然這樣會浪費很多的頻寬等資源。
HTML5 定義的 WebSocket 協議,能更好的節省伺服器資源和頻寬,並且能夠更實時地進行通訊。
詳細的WebSocket介紹請參考菜鳥教程WebSocket
因為近期所使用的技術棧為VUE和SpringBoot,因此此文章所用技術環境也為VUE以及SpringBoot下。
建議先在後端(SpringBoot)配置好WebSocket。
maven依賴(因為我的SpringBoot專案為2.0以上,會自動選擇最優版本,因此此處沒有帶上版本號):
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-websocket</artifactId> </dependency>
WebSocket配置類:
@Configuration public class WebSocketConfig { /** * 注入ServerEndpointExporter, * 這個bean會自動註冊使用了@ServerEndpoint註解宣告的Websocket endpoint */ @Bean public ServerEndpointExporter serverEndpointExporter() { return new ServerEndpointExporter(); } }
WebSocket操作類:
WebSocket的向用戶推送可以為向所有使用者推送以及單點推送
@Component
@ServerEndpoint("/websocket/{shopId}")
//此註解相當於設定訪問URL
public class WebSocket {
private Session session;
private static CopyOnWriteArraySet<WebSocket> webSockets =new CopyOnWriteArraySet<>();
private static Map<String,Session> sessionPool = new HashMap<String,Session>();
@OnOpen
public void onOpen(Session session, @PathParam(value="shopId")String shopId) {
this.session = session;
webSockets.add(this);
sessionPool.put(shopId, session);
System.out.println("【websocket訊息】有新的連線,總數為:"+webSockets.size());
}
@OnClose
public void onClose() {
webSockets.remove(this);
System.out.println("【websocket訊息】連線斷開,總數為:"+webSockets.size());
}
@OnMessage
public void onMessage(String message) {
System.out.println("【websocket訊息】收到客戶端訊息:"+message);
}
// 此為廣播訊息
public void sendAllMessage(String message) {
for(WebSocket webSocket : webSockets) {
System.out.println("【websocket訊息】廣播訊息:"+message);
try {
webSocket.session.getAsyncRemote().sendText(message);
} catch (Exception e) {
e.printStackTrace();
}
}
}
// 此為單點訊息
public void sendOneMessage(String shopId, String message) {
Session session = sessionPool.get(shopId);
if (session != null) {
try {
session.getAsyncRemote().sendText(message);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
在Controller中使用
@RestController
@RequestMapping("api")
public class TestController {
@Autowired
private WebSocket webSocket;
@RequestMapping("/sendAllWebSocket")
public String test() {
webSocket.sendAllMessage("清晨起來開啟窗,心情美美噠~");
return "websocket群體傳送!";
}
@RequestMapping("/sendOneWebSocket")
public String sendOneWebSocket() {
webSocket.sendOneMessage("DPS007", "只要你乖給你買條gai!");
return "websocket單人傳送";
}
}
在前端中(VUE)使用WebSocket
當然不在vue中使用也是一樣的,只不過要注意的是WebSocket在普通js中如何建立以及銷燬
<script>
export default {
data() {
return {
shopId:''
}
},
created() { // 頁面建立生命週期函式
this.initWebSocket()
},
destroyed: function () { // 離開頁面生命週期函式
this.websocketclose();
},
methods: {
collapse: function(){
this.isCollapse = !this.isCollapse;
if (this.isCollapse) {
this.iconClass = "cebianlanzhankai";
} else{
this.iconClass = "cebianlanshouhui";
}
},
initWebSocket: function () {
// WebSocket與普通的請求所用協議有所不同,ws等同於http,wss等同於https
this.websock = new WebSocket("ws://localhost:8046/websocket/DPS007");
this.websock.onopen = this.websocketonopen;
this.websock.onerror = this.websocketonerror;
this.websock.onmessage = this.websocketonmessage;
this.websock.onclose = this.websocketclose;
},
websocketonopen: function () {
console.log("WebSocket連線成功");
},
websocketonerror: function (e) {
console.log("WebSocket連線發生錯誤");
},
websocketonmessage: function (e) {
var da = JSON.parse(e.data);
console.log(da);
this.message = da;
},
websocketclose: function (e) {
console.log("connection closed (" + e.code + ")");
}
}
}
</script>
原文地址:https://segmentfault.com/a/1190000017268973