1.簡單介紹
基于webSocket通信的庫主要有 socket.io务嫡,SockJS,這次用的是 SockJS漆改。
2.前提
要進行文章中的代碼的測試,需要后端開發(fā)人員配合你,提供相關(guān)的通信接口.來完成客戶端和服務(wù)端的通信.實現(xiàn)通信,我們需要用到另個模塊sockjs-client模塊和stomjs模塊
關(guān)于實時通信
實現(xiàn)實時通信,我們通常有三種方法:
1.ajax輪詢---ajax輪詢的原理非常簡單,讓瀏覽器每隔幾秒就像服務(wù)器發(fā)送一個請求,詢問服務(wù)器是否有新的信息.
2.http 長輪詢---長輪詢的機制和ajax輪詢差不多,都是采用輪詢的方式,不過才去的是阻塞模型(一直打電話,沒收到就不掛電話),也就是說,客戶端發(fā)起鏈接后,如果沒有消息,就一直不返回response給客戶端.知道有新的消息才返回,返回完之后,客戶端再此建立連接,周而復(fù)始.
3.WebSocket---WebSocket是HTML5開始提供的一種在單個TCP連接上進行全雙工通訊的協(xié)議.在WebSocket API中心铃,瀏覽器和服務(wù)器只需要做一個握手的動作,然后挫剑,瀏覽器和服務(wù)器之間就形成了一條快速通道去扣。兩者之間就直接可以數(shù)據(jù)互相傳送,不需要繁瑣的詢問和等待.
從上面的介紹很容易看出來,ajax輪詢和長輪詢都是非常耗費資源的,ajax輪詢需要服務(wù)器有很快的處理速度和資源,http長輪詢需要有很高的并發(fā),也就是同時接待客戶的能力.而WebSocket,只需要經(jīng)過一次HTTP請求,就可以與服務(wù)端進行源源不斷的消息收發(fā)了.
sockjs-client
sockjs-client是從SockJS中分離出來的用于客戶端使用的通信模塊.所以我們就直接來看看SockJS.SockJS是一個瀏覽器的JavaScript庫,它提供了一個類似于網(wǎng)絡(luò)的對象,SockJS提供了一個連貫的,跨瀏覽器的JavaScriptAPI,它在瀏覽器和Web服務(wù)器之間創(chuàng)建了一個低延遲,全雙工,跨域通信通道.你可能會問,我為什么不直接用原生的WebSocket而要使用SockJS呢?這得益于SockJS的一大特性,一些瀏覽器中缺少對WebSocket的支持,因此,回退選項是必要的樊破,而Spring框架提供了基于SockJS協(xié)議的透明的回退選項愉棱。SockJS提供了瀏覽器兼容性,優(yōu)先使用原生的WebSocket,如果某個瀏覽器不支持WebSocket,SockJS會自動降級為輪詢.
stomjs
STOMP(Simple Text-Orientated Messaging Protocol) 面向消息的簡單文本協(xié)議;
WebSocket是一個消息架構(gòu),不強制使用任何特定的消息協(xié)議,它依賴于應(yīng)用層解釋消息的含義.
與HTTP不同,WebSocket是處在TCP上非常薄的一層,會將字節(jié)流轉(zhuǎn)化為文本/二進制消息,因此,對于實際應(yīng)用來說,WebSocket的通信形式層級過低,因此,可以在 WebSocket 之上使用STOMP協(xié)議哲戚,來為瀏覽器 和 server間的 通信增加適當(dāng)?shù)南⒄Z義奔滑。
STOMP與WebSocket 的關(guān)系:
1.HTTP協(xié)議解決了web瀏覽器發(fā)起請求以及web服務(wù)器響應(yīng)請求的細節(jié),假設(shè)HTTP協(xié)議不存在,只能使用TCP套接字來編寫web應(yīng)用,你可能認為這是一件瘋狂的事情;
2.直接使用WebSocket(SockJS)就很類似于使用TCP套接字來編寫web應(yīng)用,因為沒有高層協(xié)議,就需要我們定義應(yīng)用間發(fā)送消息的語義,還需要確保連接的兩端都能遵循這些語義;
3.同HTTP在TCP套接字上添加請求-響應(yīng)模型層一樣,STOMP在WebSocket之上提供了一個基于幀的線路格式層,用來定義消息語義
代碼實現(xiàn)
先安裝 sockjs-client 和 stompjs
npm install sockjs-client
npm install stompjs
如果單獨安裝npm install stompjs不成功,可以試試直接復(fù)制2行命令直接安裝.
// 引入 wensocket 模塊 監(jiān)聽數(shù)據(jù)變化
import SockJS from 'sockjs-client';
import Stomp from 'stompjs';
export default {
data(){
return {
stompClient:'',
timer:'',
}
},
methods:{
initWebSocket() {
this.connection();
let that= this;
// 斷開重連機制,嘗試發(fā)送消息,捕獲異常發(fā)生時重連
this.timer = setInterval(() => {
try {
that.stompClient.send("test");
} catch (err) {
console.log("斷線了: " + err);
that.connection();
}
}, 5000);
},
connection() {
// 建立連接對象
let socket = new SockJS('https://hkcx.io/cct/cct-websocket');
// 獲取STOMP子協(xié)議的客戶端對象
this.stompClient = Stomp.over(socket);
// 定義客戶端的認證信息,按需求配置
let headers = {
Authorization:''
}
// 向服務(wù)器發(fā)起websocket連接
this.stompClient.connect(headers,() => {
this.stompClient.subscribe('/topic/public', (msg) => { // 訂閱服務(wù)端提供的某個topic
console.log('廣播成功')
console.log(msg); // msg.body存放的是服務(wù)端發(fā)送給我們的信息
// 所要監(jiān)聽的數(shù)據(jù)函數(shù)
this.initUsdList();
this.initRange();
},headers);
this.stompClient.send("/app/chat.addUser",
headers,
JSON.stringify({sender: '',chatType: 'JOIN'}),
) //用戶加入接口
}, (err) => {
// 連接發(fā)生錯誤時的處理函數(shù)
console.log('失敗')
console.log(err);
});
}, //連接 后臺
disconnect() {
if (this.stompClient) {
this.stompClient.disconnect();
}
}, // 斷開連接
},
mounted(){
this.initWebSocket();
},
beforeDestroy: function () {
// 頁面離開時斷開連接,清除定時器
this.disconnect();
clearInterval(this.timer);
}
}
最為重要的兩點就是
// 建立連接對象
let socket = new SockJS('https://hkcx.io/cct/cct-websocket');
this.stompClient.subscribe(
'/topic/subscription',
msg => {
// 訂閱服務(wù)端提供的某個topic
console.log('連接成功');
console.log(msg); // msg.body存放的是服務(wù)端發(fā)送給我們的信息
// 所要監(jiān)聽的數(shù)據(jù)函數(shù)
this.initUsdList();
this.initRange();
},
headers
);
this.stompClient.send(
'/topic/subscription',
headers,
JSON.stringify({sender: '', chatType: 'JOIN'})
); //用戶加入接口
},
這個鏈接口是需要后端提供給你通信接口!其次就是我們所要監(jiān)聽的函數(shù)寫入這里
this.stompClient.subscribe(
'/topic/subscription',
msg => {
// 訂閱服務(wù)端提供的某個topic
console.log('連接成功');
console.log(msg); // msg.body存放的是服務(wù)端發(fā)送給我們的信息
// 所要監(jiān)聽的數(shù)據(jù)函數(shù)
this.initUsdList();
this.initRange();
},
headers
);