摘要:接口用于接收服務器發送的事件。因此,是目前來說最佳的選擇。最大特點就是,服務器可以主動向客戶端推送消息,客戶端也可以主動向服務器發送信息,是一種不受限的全雙工通信。若是,則交給的回調函數處理,否則,還是走正常的回調的路子。
使用 WebSocket 的理由
傳統的http協議有一個根本性的缺陷,那就是請求只能由客戶端向服務器發起,服務器接收到請求后再進行響應,把數據返回給客戶端。也就是說,服務器是沒有辦法主動向客戶端傳送消息的。
這樣一來,如果服務器有狀態是頻繁變化的,那么,客戶端想要實時獲悉這些狀態勢必非常麻煩。如在線多人游戲,聊天室等。
一種可行的解決方案是使用輪詢。輪詢是指瀏覽器通過JavaScript啟動一個定時器,然后以固定的間隔給服務器發請求,詢問服務器有沒有新消息。
這種機制不僅效率低下,實時性不夠,而且頻繁地發起請求也會給服務器帶來極大的壓力。
另外一種比較靠譜的技術是HTML5的EventSource。EventSource 接口用于接收服務器發送的事件。它通過HTTP連接到一個服務器,以text/event-stream 格式接收事件, 不關閉連接。
相對于WebSocket,這種技術要簡單很多,但是其只是從服務器端往客戶端單向傳輸數據,并不能實現真正意義上的全雙工通信。因此,WebSocket是目前來說最佳的選擇。
有興趣了解EventSource的小伙伴可以點擊這里
WebSocket 協議WebSocket是HTML5新增的協議,其誕生于2008年。最大特點就是,服務器可以主動向客戶端推送消息,客戶端也可以主動向服務器發送信息,是一種不受限的全雙工通信。
該協議有以下特征:
握手階段利用了HTTP協議來建立連接,因此WebSocket連接必須由瀏覽器發起。
建立在 TCP 協議之上,服務器端的實現比較容易。
其可以接收和發送的數據有兩種,一種是文本,一種是二進制數據(blob對象或Arraybuffer對象)。一般情況下,我們可以發送JSON格式的文本,這樣,在瀏覽器處理起來就十分容易。
數據格式比較輕量,性能開銷小,通信高效。
請求是以ws://為開頭的地址(如果加密,則為wss://)。
WebSocket協議本身不要求同源策略,也就是某個地址為"http://a.com"的網頁可以通過WebSocket連接到"ws://b.com"。但是,瀏覽器會發送Origin的HTTP頭給服務器,服務器可以根據Origin拒絕這個WebSocket請求。
瀏覽器支持情況Chrome
Firefox
IE >= 10
Sarafi >= 6
Android >= 4.4
iOS >= 8
服務端實現不同的編程語言和框架,實現方式各有不同。這里主要講一下用node如何實現。
node常用的實現有一下幾種:
Socket.IO
WebSocket-Node
μWebSockets
具體如何使用可以查看它們各自的api。下面,我要詳細介紹的是另一個WebSocket模塊ws。
通過npm install ws --save之后,我們就可以可以編寫一個簡單WebSocket服務器程序。
// 首先導入ws模塊 let WebSocket = require("ws"); // 通過ws模塊的Server類實例化一個websocket服務器 let webSocketServer = new WebSocket.Server({ port: 8030 }, err => { console.log("The WebSocket Server already running on: 8030"); }); // 監聽客戶端請求接入的connection事件,連接建立后,回調函數中會傳入這個WebSocket連接實例 webSocketServer.on("connection", ws => { console.log(`Server is connected`) // 對于每個WebSocket連接,可以綁定監聽某些事件來進行不同的處理。這里,通過響應message事件,在收到客戶端發來消息后再返回一個消息過去。 ws.on("message", mes => { console.log(`Message sent by client: ${mes}`); ws.send(`data responded by Server: ${mes}`, err => { if (err) { console.log(`Server error: ${err}`); } }) }) })
也可以對http服務器進行拓展,在其基礎上建立WebSocket服務器。
const Koa = require("koa"); const WebSocket = require("ws"); const bodyParser = require("koa-bodyparser"); const controller = require("./controller.js"); const server = new Koa(); const webSocketServer = new WebSocket.Server({server}, () => console.log("The WebSocket Server already running on: 8030")); // 為websocket服務器添加一個broadcast()方法 webSocketServer.broadcast = data => { // 通過遍歷webSocketServer.clients,找到所有與該服務器成功建立websocket連接的客戶端,發送同一條消息 for (const client of webSocketServer.clients) { if (client.readyState === WebSocket.OPEN) { client.send(data, err => console.log(`Server error: ${err}`)); } } } webSocketServer.on("connection", ws => { console.log(`Server is connected`); ws.on("message", mes => { console.log(`Message sent by client: ${mes}`); // 接受到其中一個客戶端發來的消息后,廣播給所有同時連接過來的客戶端 const data = { message: mes } webSocketServer.broadcast(JSON.stringify(data)) }) }) server.use(bodyParser()); server.use(controller()); server.listen(8030); console.log("server running on 8030...");
現在,websocket服務器與http服務器同時使用8030端口。當有一個請求發送過來,首先會判斷其是否ws請求。若是,則交給WebSocketServer的回調函數處理,否則,還是走正常的http server回調的路子。
另外,我們注意到,這里還給WebSocketServer添加了一個broadcast()方法,用于將消息廣播到所有與該服務器成功建立WebSocket連接的客戶端上。
每當從其中一個客戶端收到一條消息,就將該消息發送到所有WebSocket連接上,基于這種方式,我們就可以搭建一個聊天室應用的后臺服務。
ws模塊的完整使用方法請看這里
客戶端實現客戶端要創建一個WebSocket連接就比較簡單了。下面是一個簡單的事例:
// 創建一個WebSocket連接: var ws = new WebSocket("ws://localhost:8030/ws"); ws.onopen = function(event) { console.log("Connection open"); // 給服務器發送一個消息: ws.send("Hello WebSocket!"); }; // 響應onmessage事件: ws.onmessage = function(event) { console.log(event.data); }; // 也可以指定接收的二進制數據類型為blob對象 ws.binaryType = "blob"; ws.onmessage = function(event) { console.log(event.data.size); }; // 或 // 指定接收的二進制數據類型為ArrayBuffer對象 ws.binaryType = "arraybuffer"; ws.onmessage = function(event) { console.log(event.data.byteLength); };
詳細的屬性和方法可以看這里
另外,使用ws模塊提供的WebSocket構造函數也可以充當客戶端創建連接。
let ws = new WebSocket("ws://localhost:8030/ws"); // 打開WebSocket連接后立刻發送一條消息 ws.on("open", () => { console.log(`Client open`); ws.send("Hello WebSocket!"); }); // 響應收到的消息 ws.on("message", mes => { console.log(mes); });參考鏈接
http://www.ruanyifeng.com/blo...
https://www.liaoxuefeng.com/w...
http://es6.ruanyifeng.com/#do...
https://developer.mozilla.org...
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/99736.html
摘要:哪吒社區技能樹打卡打卡貼函數式接口簡介領域優質創作者哪吒公眾號作者架構師奮斗者掃描主頁左側二維碼,加入群聊,一起學習一起進步歡迎點贊收藏留言前情提要無意間聽到領導們的談話,現在公司的現狀是碼農太多,但能獨立帶隊的人太少,簡而言之,不缺干 ? 哪吒社區Java技能樹打卡?【打卡貼 day2...
摘要:聲明的變量不得改變值,這意味著,一旦聲明變量,就必須立即初始化,不能留到以后賦值。 雖然今年沒有換工作的打算 但為了跟上時代的腳步 還是忍不住整理了一份最新前端知識點 知識點匯總 1.HTML HTML5新特性,語義化瀏覽器的標準模式和怪異模式xhtml和html的區別使用data-的好處meta標簽canvasHTML廢棄的標簽IE6 bug,和一些定位寫法css js放置位置和原因...
閱讀 2400·2021-09-08 09:45
閱讀 3340·2021-09-08 09:45
閱讀 3097·2019-08-30 15:54
閱讀 3348·2019-08-26 13:54
閱讀 1405·2019-08-26 13:26
閱讀 1384·2019-08-26 13:23
閱讀 909·2019-08-23 17:57
閱讀 2178·2019-08-23 17:14