WebSocket 是一個應(yīng)用層協(xié)議,有點類似 HTTP。但和 HTTP 不一樣的是,它支持真正的全雙工,即不僅客戶端可以主動發(fā)消息給服" />

国产成人精品无码青草_亚洲国产美女精品久久久久∴_欧美人与鲁交大毛片免费_国产果冻豆传媒麻婆精东

15158846557 在線咨詢 在線咨詢
15158846557 在線咨詢
所在位置: 首頁 > 營銷資訊 > 網(wǎng)站運營 > WebSocket 入門:簡易聊天室

WebSocket 入門:簡易聊天室

時間:2023-07-22 07:30:02 | 來源:網(wǎng)站運營

時間:2023-07-22 07:30:02 來源:網(wǎng)站運營

WebSocket 入門:簡易聊天室:大家好,我是前端西瓜哥,今天我們用 WebSocket 來實現(xiàn)一個簡單的聊天室。

WebSocket 是一個應(yīng)用層協(xié)議,有點類似 HTTP。但和 HTTP 不一樣的是,它支持真正的全雙工,即不僅客戶端可以主動發(fā)消息給服務(wù)端,服務(wù)端也可以主動發(fā)消息給客戶端。

尤其是后者,讓我們不用再基于 HTTP 長輪詢或短輪詢的低效方式來實現(xiàn)服務(wù)端通知。相比 HTTP,WebSocket 的服務(wù)端推送更輕量,并能減少服務(wù)端的壓力。

服務(wù)端

nodejs 并沒有提供原生的 WebSocket 模塊。如果要實現(xiàn),需要基于 net 模塊,根據(jù) WebSocket 標(biāo)準(zhǔn)去做實現(xiàn)。

因為實現(xiàn)很復(fù)雜,所以西瓜哥我選擇直接用第三庫 ws。

yarn add ws類似 nodejs 原生的 http 等模塊,ws 庫支持 WebSocket 的服務(wù)端或客戶端, 提供偏底層的 API。

我們先實現(xiàn)服務(wù)端代碼:

import { WebSocketServer } from "ws";// 創(chuàng)建一個 ws 服務(wù)const wsSever = new WebSocketServer({ port: 6060,});// 每當(dāng)一個客戶端進行了 ws 連接,就會創(chuàng)建一個 ws 對象wsSever.on("connection", (ws) => { // 新客戶端連接時,廣播 wsSever.clients.forEach((client) => { client.send(`有人進入聊天室,當(dāng)前聊天室人數(shù):${wsSever.clients.size}`); }); // 廣播任何客戶端發(fā)送的消息 ws.on("message", (data) => { const msg = data.toString(); wsSever.clients.forEach((client) => { client.send(msg); }); }); // 當(dāng)有客戶端退出時,廣播 ws.on("close", () => { wsSever.clients.forEach((client) => { client.send(`有人退出了聊天室,當(dāng)前聊天室人數(shù):${wsSever.clients.size}`); }); });});每當(dāng)一個客戶端進行了 websocket 連接,都會觸發(fā) wsServer 的 connection 事件,然后拿到一個 ws 對象。

這個 ws 對象代表了某個客戶端和服務(wù)端的連接,我們可以通過它來接收對應(yīng)客戶端的消息,并讓服務(wù)端對指定客戶端進行主動消息推送。

新創(chuàng)建的 ws 對象會在建立連接時保存到 wsServer.clients 集合下,并在關(guān)閉連接后移除。所以我們可以利用這個 wsServer.clients 來進行廣播,實現(xiàn)聊天室功能。

客戶端

客戶端使用原生的 WebSocket 對象,來和服務(wù)端進行 WebSocket 連接。

const ws = new WebSocket('ws://localhost:6060');ws.addEventListener('message', (event) => { const div = document.createElement('div'); div.innerText = event.data; document.body.append(div);})// 點擊發(fā)送按鈕,將輸入框中的內(nèi)容發(fā)送給服務(wù)器const input = document.querySelector('input');const btn = document.querySelector('button');btn.onclick = () => { ws.send(input.value); input.value = '';}

效果

改為使用 http://Socket.IO

ws 庫是偏底層的實現(xiàn),比較簡單。

另一個庫 http://Socket.IO 的底層使用了 ws,并做功能上的增強,提供更多的能力。

相比 ws,http://Socket.IO 能夠做到:

  1. 如果瀏覽器不支持 WebSocket,回退為 HTTP 長輪詢方案來模擬 WebSocket( WebSocket 于 2011 年完成 RFC,已經(jīng)很久了,目前來說主流瀏覽器都已經(jīng)支持 WebSocket 了,還不支持 WebSocket 的瀏覽器是屑);
  2. 使用心跳包機制實現(xiàn)了自動重連。
  3. 包緩存。斷連時發(fā)送數(shù)據(jù),會將數(shù)據(jù)保存下來,等重新連接后再發(fā)送;
  4. 自定義事件支持;
  5. 廣播;
相比自己去一個個實現(xiàn),使用流行的輪子可能是更好的選擇。

我們將前面的功能用 http://Socket.IO 實現(xiàn)一下。

服務(wù)端:

import { Server } from "socket.io";// socket.io v3.x 開始默認不允許跨域,需要在配置顯式設(shè)置為允許跨域const io = new Server(6060, { cors: { origin: "*" } });io.on("connection", (socket) => { // 新客戶端連接時,廣播 io.emit("chat", `有人進入聊天室,當(dāng)前聊天室人數(shù):${io.engine.clientsCount}`); // 廣播任何客戶端發(fā)送的消息 socket.on("chat", (data) => { io.emit("chat", data); }); // 當(dāng)有客戶端退出時,廣播 socket.on("disconnect", () => { io.emit("chat", `有人退出了聊天室,當(dāng)前聊天室人數(shù):${io.engine.clientsCount}`); });});需要特別注意的是,http://Socket.IO 的 v3.x 版本開始,默認不允許跨域,需要在配置顯式設(shè)置為允許跨域。

客戶端:

const socket = io('ws://localhost:6060');socket.on('chat', (data) => { const div = document.createElement('div'); div.innerText = data; document.body.append(div);})// 點擊發(fā)送按鈕,將輸入框中的內(nèi)容發(fā)送給服務(wù)器const input = document.querySelector('input');const btn = document.querySelector('button');btn.onclick = () => { console.log('發(fā)送'); socket.emit('chat', input.value); input.value = '';}http://Socket.IO 優(yōu)點是實現(xiàn)了生產(chǎn)環(huán)境需要的底層非業(yè)務(wù)能力,讓我們能更心無旁騖地去編寫業(yè)務(wù)代碼。

缺點是丟失了靈活性。因為做了定制化,所以需要配套使用 http://Socket.IO 的客戶端和服務(wù)端庫的包,某種意義脫離了網(wǎng)絡(luò)協(xié)議標(biāo)準(zhǔn)。在出現(xiàn)跨語言(比如前端是 JS,后端是 Java)的場景時,需要提供對應(yīng)的語言的 http://Socket.IO 實現(xiàn)。

demo

demo 已經(jīng)放到 github 上了,使用方法在 README.md 中有說明。

https://github.com/F-star/websocket-chat-demo

結(jié)尾

本文演示了 WebSocket 簡易的聊天室功能是如何實現(xiàn)的,希望對你有所幫助。

我是前端西瓜哥,歡迎關(guān)注我,學(xué)習(xí)更多前端知識。



關(guān)鍵詞:簡易,入門

74
73
25
news

版權(quán)所有? 億企邦 1997-2025 保留一切法律許可權(quán)利。

為了最佳展示效果,本站不支持IE9及以下版本的瀏覽器,建議您使用谷歌Chrome瀏覽器。 點擊下載Chrome瀏覽器
關(guān)閉