websocket通訊的建立階段是依賴于http協議的。最初的握手階段是http協議,握手完成后就切換到websocket協議,并完全與http協議脫離了。
建立通訊時,也是由客戶端主動發起連接請求,服務端被動監聽。
通訊一旦建立連接后,通訊就是“全雙工”模式了。也就是說服務端和客戶端都能在任何時間自由得發送數據,非常適合服務端要主動推送實時數據的業務場景。
交互模式不再是“請求-應答”模式,完全由開發者自行設計通訊協議。
通信的數據是基于“幀(frame)”的,可以傳輸文本數據,也可以直接傳輸二進制數據,效率高。當然,開發者也就要考慮封包、拆包、編號等技術細節。
沒有同源限制,客戶端可以與任意服務器通信。
協議標識符是ws(如果加密,則為wws),服務器網址是url。
服務端監聽通訊,被動提供服務;客戶端主動向服務端發起連接請求,建立起通訊。
每一次交互都是:客戶端主動發起請求(request),服務端被動應答(response)。
服務端不能主動向客戶端推送數據。
通信的數據是基于文本格式的。二進制數據(比如圖片等)要利用base64等手段轉換為文本后才能傳輸。
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <meta name="viewport" content="width=device-width, initial-scale=1.0"> 6 <meta http-equiv="X-UA-Compatible" content="ie=edge"> 7 <title>webSocket封裝</title> 8 </head> 9 <body> 10 <script> 11 /* webSocket封裝 12 * @param url: webSocket接口地址與攜帶參數(必填) 13 * @param onopen(): 連接成功后的回調函數 14 * @param onmessage(): 接收到服務器數據后的回調函數 15 * @param onclose(): 連接關閉后的回調函數 16 * @param onerror(): 連接發生錯誤后的回調函數 17 * @param heartMessage: 發送給后臺的心跳包參數(必填),給服務器端的心跳包就是定期給服務器發送消息 18 * @param timer: 給后臺傳送心跳包的時間間隔,不傳時使用默認值3000毫秒 19 * @param isReconnect: 連接斷掉是否重新連接,傳true為重新連接 20 */ 21 function useWebSocket(url,onOpenFunc,onMessageFunc,onCloseFunc,onErrorFunc,heartMessage,timer,isReconnect){ 22 let isConnected = false; //設置已連接webSocket標識 23 let ws = null; //定義webSocket對象 24 //創建并連接webSocket 25 let connect = function(){ 26 if(!isConnected){ 27 //若未連接webSocket,則創建一個新的webSocket 28 console.log(url); 29 ws = new WebSocket(url); 30 isConnected = true; 31 } 32 } 33 //向后臺發送心跳消息 34 let heartCheck = function(){ 35 ws.send(JSON.stringify(heartMessage)); 36 } 37 //初始化事件回調函數 38 let initEventHandle = function(){ 39 console.log('已連接'); 40 ws.addEventListener('open',function(event){ 41 //給后臺發心跳請求 42 heartCheck(); 43 //若傳入函數,執行onOpenFunc 44 if(!onOpenFunc){ 45 return false; 46 }else{ 47 onOpenFunc(event); 48 } 49 }) 50 ws.addEventListener('message',function(event){ 51 //接收到任何后臺的消息都說明當前連接是正常的 52 if(!event){ 53 return false; 54 }else{ 55 //若獲取到后臺消息,則timer毫秒后再次發起心跳請求給后臺,檢測是否斷開連接 56 setTimeout(()=>{ 57 heartCheck(); //給后臺發心跳請求 58 },!timer ? 3000 : timer) 59 } 60 //若傳入了函數,執行onMessageFunc 61 if(!onMessageFunc){ 62 return false; 63 }else{ 64 onMessageFunc(event); 65 } 66 }) 67 ws.addEventListener('close',function(event){ 68 //若傳入函數,執行onCloseFunc 69 if(!onCloseFunc){ 70 return false; 71 }else{ 72 onCloseFunc(event); 73 } 74 if(isReconnect){ //若斷開立即重新連接標志為true 75 connect(); //重新連接webSocket 76 } 77 }) 78 ws.addEventListener('error',function(event){ 79 //若傳入函數,執行onErrorFunc 80 if(!onErrorFunc){ 81 return false; 82 }else{ 83 onErrorFunc(event); 84 } 85 if(isReconnect){ //若斷開立即重新連接標志為true 86 connect(); //重新連接webSocket 87 } 88 }) 89 } 90 window.onload = function(){ 91 //初始化webSocket 92 (function(){ 93 //1.創建并連接webSocket 94 connect(); 95 //2.初始化事件回調函數 96 initEventHandle(); 97 //3.返回是否已連接 98 return ws; 99 })()100 }101 }102 useWebSocket("ws://10.170.6.45:8888/websocket/23", //服務器url103 null, //onopen的回調函數 104 function(event){105 let res = event.data; //后端返回的數據,onmessage的回調函數106 console.log(res);107 },108 null, //onclose的回調函數 109 null, //onerror的回調函數 110 { //心跳包消息111 "action":"66",112 "eventType":"88",113 "requestId":"123"114 },115 null, //傳送心跳包的間隔時間116 true //true表示連接斷開立即重新連接 117 )118 </script>119 </body>120 </html>來源:https://www.icode9.com/content-4-592901.html