node.js實現(xiàn)websocket的即時通訊詳解
前言
websocket
,WebSocket并不是全新的協(xié)議,而是利用了HTTP協(xié)議來建立連接,接下來讓我們正式走進websocket的大門!
為什么需要 WebSocket?
初次接觸 WebSocket
,大家都會問同樣的問題:我們已經(jīng)有了 HTTP
協(xié)議,為什么還需要另一個協(xié)議?它能帶來什么好處? 答案很簡單,因為 HTTP 協(xié)議有一個缺陷
:通信只能由客戶端發(fā)起。 舉例來說,我們想了解今天的天氣,只能是客戶端
向服務(wù)器
發(fā)出請求,服務(wù)器返回查詢結(jié)果。HTTP 協(xié)議做不到服務(wù)器主動向客戶端推送信息
。
這種單向請求的特點,注定了如果服務(wù)器有連續(xù)的狀態(tài)變化,客戶端要獲知就非常麻煩。我們只能使用"輪詢
":每隔一段時候,就發(fā)出一個詢問,了解服務(wù)器有沒有新的信息
。最典型的場景就是聊天室
。
輪詢的效率低,非常浪費資源
(因為必須不停連接,或者 HTTP 連接始終打開)。因此,工程師們一直在思考,有沒有更好的方法。WebSocket 就是這樣發(fā)明的。
WebSocket簡介
服務(wù)器可以主動
向客戶端推送信息,客戶端也可以主動向服務(wù)器發(fā)送信息,是真正的雙向平等對話
,屬于服務(wù)器推送技術(shù)
的一種。
為什么WebSocket連接可以實現(xiàn)全雙工通信
而HTTP連接不行呢?實際上HTTP協(xié)議是建立在TCP協(xié)議
之上的,TCP協(xié)議本身就實現(xiàn)了全雙工通信,但是HTTP協(xié)議的請求-應(yīng)答機制
限制了全雙工通信。WebSocket連接建立以后,其實只是簡單規(guī)定了一下:接下來,咱們通信就不使用HTTP協(xié)議了,直接互相發(fā)數(shù)據(jù)吧
。
注意:WebSocket連接必須由瀏覽器發(fā)起,因為請求協(xié)議是一個標(biāo)準(zhǔn)的HTTP請求
Websocket的特點 建立在 TCP 協(xié)議
之上,服務(wù)器端的實現(xiàn)比較容易。與 HTTP 協(xié)議有著良好的兼容性。默認(rèn)端口也是80和443
,并且握手階段
采用 HTTP 協(xié)議,因此握手時不容易屏蔽,能通過各種 HTTP 代理服務(wù)器。數(shù)據(jù)格式比較輕量,性能開銷小,通信高效??梢?code>發(fā)送文本,也可以發(fā)送二進制數(shù)據(jù)
。沒有同源限制
,客戶端可以與任意服務(wù)器通信。協(xié)議標(biāo)識符是ws
(如果加密,則為wss),服務(wù)器網(wǎng)址就是 URL(例如:ws://localhost:8080
)。
WebSocket的應(yīng)用場景
- 彈幕
- 媒體聊天
- 協(xié)同編輯(
我們常用的在線編輯
) - 基于位置的應(yīng)用(例如:
美團外賣中我們可以實時查看外賣小哥的位置,距離目的地的距離
) - 體育實況更新(
騰訊體育nba直播技術(shù)統(tǒng)計的數(shù)據(jù)實時更新
) - 股票基金報價實時更新
服務(wù)器支持
由于WebSocket是一個協(xié)議,服務(wù)器具體怎么實現(xiàn),取決于所用編程語言和框架本身
。Node.js本身支持的協(xié)議包括TCP協(xié)議
和HTTP協(xié)議
,要支持WebSocket協(xié)議,需要對Node.js提供的HTTPServer做額外的開發(fā)
。已經(jīng)有若干基于Node.js的穩(wěn)定可靠的WebSocket實現(xiàn),我們直接用npm
安裝使用即可。
客戶端websocket的 API
WebScoket構(gòu)造函數(shù)
const ws = new WebSocket(`ws://localhost:8080?token=${localStorage.getItem("token")}`)
WebSocket 對象作為一個構(gòu)造函數(shù),用于新建 WebSocket 實例。執(zhí)行上面語句之后,客戶端就會與服務(wù)器進行連接
。 注意: 在這里傳入的參數(shù)url中可以攜帶token
,可以進行登錄鑒權(quán)
!
ws.onopen()
實例對象的onopen
屬性,用于指定連接成功后的回調(diào)函數(shù)
。
ws.onopen = () => { console.log('連接成功!'); }
ws.onclose()
實例對象的onclose
屬性,用于指定連接關(guān)閉后的回調(diào)函數(shù)
。
ws.onclose = () => { console.log('關(guān)閉成功!') }
ws.onmessage()
實例對象的onmessage
屬性,用于指定收到服務(wù)器數(shù)據(jù)后的回調(diào)函數(shù)
。
ws.onmessage = (msgObj) => { //...在這里進行邏輯操作 }
注意:這里的形參是服務(wù)器傳來的數(shù)據(jù)對象,msgObj.data可以訪問到服務(wù)端返回的具體信息數(shù)據(jù)
ws.send()
實例對象的send()
方法用于向服務(wù)器發(fā)送數(shù)據(jù)
。
ws.send('hello websocket')
node中使用WebSocket
客戶端使用
var ws = new WebSocket(`ws://localhost:8080?token=${localStorage.getItem("token")}`) ws.onopen = () => { console.log("open") ws.send(JSON.stringify({ type: WebSocketType.GroupList })) } ws.onmessage = (evt) => { console.log(evt.data) }
在上面我們對客戶端的方法做了一個了解后,將對服務(wù)端進行了解!=>node中使用websocket官網(wǎng)
安裝ws模塊
npm install ws
node中簡單使用
const WebSocket = require("ws") const WebSocketServer = WebSocket.WebSocketServer //創(chuàng)建websocket服務(wù),端口號為8080,與客戶端請求的端口號保持一致 const wss = new WebSocketServer({ port: 8080 }); wss.on('connection', function connection(ws) { // connection,表示連接客戶端,形參中的ws代表我們的客戶端 ws.on('message', function message(data, isBinary) { //這里表示只要ws標(biāo)記的客戶端給我們發(fā)送消息,我們通過監(jiān)聽message可以得到前臺發(fā)過來的消息 wss.clients.forEach(function each(client) { //wss.clients存放著連接到我們服務(wù)器所有的客戶端,通過遍歷,將客戶端的消息轉(zhuǎn)發(fā)給其他客戶端,從而實現(xiàn)群聊 if (client !== ws && client.readyState === WebSocket.OPEN) { //這里client!==ws 目的是群發(fā)的時候不給自己發(fā)消息 client.send(data, { binary: false }); //在這里binary:false表示返回的數(shù)據(jù)不是二進制類型! } }); }); ws.send('歡迎加入聊天室'); //給客戶端返回信息 });
注意:上述代碼中
ws
實質(zhì)上是一個句柄,(按照我的理解就是:ws代表我們打開的瀏覽器窗口,每打開一個窗口,ws就代表不同的窗口,代表不同的客戶端
),用來指示服務(wù)端指向客戶端的唯一標(biāo)識
小結(jié)
WebScoket整體來說的話不是很難,只是比較繁瑣罷了,前后端必須要進行一對一的匹配,也就是說,有來就有回,本篇為wensocket學(xué)習(xí)的第一階段而已,后面的文章將會切入到群聊、私聊的demo
到此這篇關(guān)于深入淺出講解websocket的即時通訊的文章就介紹到這了,更多相關(guān)websocket即時通訊內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Node.js通過配置?strict-ssl=false解決npm安裝卡住問題
使用npm安裝依賴包是常見的任務(wù)之一,有時會遇到安裝卡住的問題,本文就來介紹一下通過配置?strict-ssl=false解決npm安裝卡住問題,感興趣的可以了解一下2024-12-12詳解在node.js中require方法的加載規(guī)則
這篇文章主要介紹了詳解在node.js中require方法的加載規(guī)則,本文一步步解析了require加載規(guī)則,講述了核心的模塊,路徑形式的模塊,第三方模塊等,需要的朋友可以參考下2021-06-06Ubuntu服務(wù)器上安裝Node.js的三種不同方法介紹
Node.js是一個強大的 JavaScript 運行時環(huán)境,使開發(fā)者能夠使用 JavaScript 創(chuàng)建服務(wù)器端應(yīng)用程序,本文將詳細介紹三種安裝 Node.js 的方法,大家根據(jù)具體需求選擇最適合的安裝方式2025-03-03nodejs結(jié)合Socket.IO實現(xiàn)的即時通訊功能詳解
這篇文章主要介紹了nodejs結(jié)合Socket.IO實現(xiàn)的即時通訊功能,結(jié)合實例形式詳細分析了nodejs結(jié)合Socket.IO實現(xiàn)即時通訊的相關(guān)操作技巧與注意事項,需要的朋友可以參考下2018-01-01Node.js基礎(chǔ)入門之回調(diào)函數(shù)及異步與同步詳解
Node.js是一個基于Chrome?V8引擎的JavaScript運行時。類似于Java中的JRE,.Net中的CLR。本文將詳細為大家介紹Node.js中的回調(diào)函數(shù)及異步與同步,感興趣的可以了解一下2022-03-03