1.介紹
websocket
建立連接(創(chuàng)建WebSocket對(duì)象):
var Socket =new WebSocket(url, [protocol] );// url:服務(wù)器端地址;protocol:可選,指定可接受的子協(xié)議。
WebSocket對(duì)象提供了兩個(gè)屬性、四個(gè)事件、兩個(gè)方法,分別是:
1.WebSocket.readyState屬性:表示連接狀態(tài)
????0——(連接尚未建立);1——(連接已建立);2——(連接正在關(guān)閉);3——(連接已經(jīng)關(guān)閉或連接不能打開(kāi))
2.WebSocket.bufferedAmount屬性:被send()放入傳輸隊(duì)列,還未發(fā)出的UTF-8文本字節(jié)數(shù)
????ws.addEventListener('open',function(event){
????????????ws.send('Hello Server!');
????});
? ? ?ws.onopen =function(){
????????ws.send('Hello Server!');
????}
3.open:WebSocket.onopen():連接建立時(shí)觸發(fā)的事件
4.message:WebSocket.onmessage(): 客戶端接收服務(wù)器端發(fā)送的信息時(shí)觸發(fā)
5.error:WebSocket.onerror():通信發(fā)生錯(cuò)誤時(shí)觸發(fā)
6.close:WebSocket.onclose():連接關(guān)閉時(shí)觸發(fā)
7.WebSocket.send():發(fā)送信息的方法
8.WebSocket.close():關(guān)閉連接方法
SOCKJS
SOCKJS 是一個(gè)瀏覽器使用的js庫(kù),它提供了一個(gè)類似網(wǎng)絡(luò)的對(duì)象,和連貫的,跨瀏覽器的jaApi,可以在瀏覽器和服務(wù)器之間創(chuàng)建一個(gè)低延遲,全雙工的跨域通信通道
SOCKJS實(shí)現(xiàn)了對(duì)瀏覽器的兼容,spring框架提供了很多透明的,回退選項(xiàng),如果遇到低版本的瀏覽器會(huì)自動(dòng)降級(jí)為輪詢,支持就用websocket
sockjs-client
sockjs-client 是從SOCKJS分離出來(lái)的客戶端使用的通信模塊
stompjs
STOMP(Simple Text-Orientated Messaging Protocol) 面向消息的簡(jiǎn)單文本協(xié)議;
websocket只是一個(gè)消息架構(gòu),不強(qiáng)制使用任何的消息協(xié)議,為了更好的在瀏覽器和服務(wù)器之間傳遞消息,使用stomp協(xié)議 的stompjs
STOMP與WebSocket 的關(guān)系:就是沒(méi)使用http而使用stomp協(xié)議,在瀏覽器和服務(wù)器之間進(jìn)行消息傳遞
1.HTTP協(xié)議解決了web瀏覽器發(fā)起請(qǐng)求以及web服務(wù)器響應(yīng)請(qǐng)求的細(xì)節(jié),假設(shè)HTTP協(xié)議不存在,只能使用TCP套接字來(lái)編寫(xiě)web應(yīng)用,你可能認(rèn)為這是一件瘋狂的事情;
2.直接使用WebSocket(SockJS)就很類似于使用TCP套接字來(lái)編寫(xiě)web應(yīng)用,因?yàn)闆](méi)有高層協(xié)議,就需要我們定義應(yīng)用間發(fā)送消息的語(yǔ)義,還需要確保連接的兩端都能遵循這些語(yǔ)義;
3同HTTP在TCP套接字上添加請(qǐng)求-響應(yīng)模型層一樣,STOMP在WebSocket之上提供了一個(gè)基于幀的線路格式層,用來(lái)定義消息語(yǔ)義、
2.使用
安裝
npm install sockjs-client --save
npm install stompjs --save
引入
import SockJS from 'sockjs-client';
import? Stomp from 'stompjs';
export default {
? ? data(){
? ? ? ? return {
? ? ? ? ? ? stompClient:'',
? ? ? ? ? ? timer:'',
? ? ? ? }
? ? },
? ? methods:{
? ? ? ? initWebSocket() {
? ? ? ? ? ? this.connection();
? ? ? ? ? ? let that= this;
? ? ? ? ? ? // 斷開(kāi)重連機(jī)制,嘗試發(fā)送消息,捕獲異常發(fā)生時(shí)重連
? ? ? ? ? ? this.timer = setInterval(() => {
? ? ? ? ? ? ? ? try {
? ? ? ? ? ? ? ? ? ? that.stompClient.send("test");
? ? ? ? ? ? ? ? } catch (err) {
? ? ? ? ? ? ? ? ? ? console.log("斷線了: " + err);
? ? ? ? ? ? ? ? ? ? that.connection();
? ? ? ? ? ? ? ? }
? ? ? ? ? ? }, 5000);
? ? ? ? },?
? ? ? ? connection() {
? ? ? ? ? ? // 建立連接對(duì)象
? ? ? ? ? ? let socket = new SockJS('execution-progress/info?t=1593744273983');
????????????var sockjs =new SockJS(url, _reserved, options);
? ? ? ? ? ? ? ? //server(string):添加到url的字符串,默認(rèn)為隨機(jī)的4位數(shù)
? ? ? ? ? ? ? ? //transports (string OR array of strings):回退傳輸列表
? ? ? ? ? ? ? ? // sessionId (number OR function):會(huì)話標(biāo)識(shí),函數(shù)必須返回一個(gè)隨機(jī)生成的字符串
? ? ? ? ? ? // 獲取STOMP子協(xié)議的客戶端對(duì)象
? ? ? ? ? ? this.stompClient = Stomp.over(socket);
? ? ? ? ? ? // 定義客戶端的認(rèn)證信息,按需求配置
? ? ? ? ? ? let headers = {
? ? ? ? ? ? ? ? Authorization:''
? ? ? ? ? ? }
? ? ? ? ? ? // 向服務(wù)器發(fā)起websocket連接
? ? ? ? ? ? this.stompClient.connect(headers,() => {
? ? ? ? ? ? ? ? this.stompClient.subscribe('/topic/public', (msg) => { // 訂閱服務(wù)端提供的某個(gè)topic
? ? ? ? ? ? ? ? ? ? console.log('廣播成功')
? ? ? ? ? ? ? ? ? ? console.log(msg);? // msg.body存放的是服務(wù)端發(fā)送給我們的信息
? ? ? ? ? ? ? ? },headers);
? ? ? ? ? ? ? ? this.stompClient.send("/app/chat.addUser",
? ? ? ? ? ? ? ? ? ? headers,
? ? ? ? ? ? ? ? ? ? JSON.stringify({sender: '',chatType: 'JOIN'}),
? ? ? ? ? ? ? ? )? //用戶加入接口
? ? ? ? ? ? }, (err) => {
? ? ? ? ? ? ? ? // 連接發(fā)生錯(cuò)誤時(shí)的處理函數(shù)
? ? ? ? ? ? ? ? console.log('失敗')
? ? ? ? ? ? ? ? console.log(err);
? ? ? ? ? ? });
? ? ? ? },? ? //連接 后臺(tái)
? ? ? ? disconnect() {
? ? ? ? ? ? if (this.stompClient) {
? ? ? ? ? ? ? ? this.stompClient.disconnect();
? ? ? ? ? ? }
? ? ? ? },? // 斷開(kāi)連接
? ? },
? ? mounted(){
? ? ? ? this.initWebSocket();
? ? },
? ? beforeDestroy: function () {
? ? ? ? // 頁(yè)面離開(kāi)時(shí)斷開(kāi)連接,清除定時(shí)器
? ? ? ? this.disconnect();
? ? ? ? clearInterval(this.timer);
? ? }
}