日本综合一区二区|亚洲中文天堂综合|日韩欧美自拍一区|男女精品天堂一区|欧美自拍第6页亚洲成人精品一区|亚洲黄色天堂一区二区成人|超碰91偷拍第一页|日韩av夜夜嗨中文字幕|久久蜜综合视频官网|精美人妻一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問(wèn)題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷解決方案
WebSocket入門(mén):簡(jiǎn)易聊天室

大家好,我是前端西瓜哥,今天我們用 WebSocket 來(lái)實(shí)現(xiàn)一個(gè)簡(jiǎn)單的聊天室。

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

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

服務(wù)端

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

因?yàn)閷?shí)現(xiàn)很復(fù)雜,所以西瓜哥我選擇直接用第三庫(kù) ws。

yarn add ws

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

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

import { WebSocketServer } from "ws";

// 創(chuàng)建一個(gè) ws 服務(wù)
const wsSever = new WebSocketServer({
port: 6060,
});

// 每當(dāng)一個(gè)客戶端進(jìn)行了 ws 連接,就會(huì)創(chuàng)建一個(gè) ws 對(duì)象
wsSever.on("connection", (ws) => {
// 新客戶端連接時(shí),廣播
wsSever.clients.forEach((client) => {
client.send(`有人進(jìn)入聊天室,當(dāng)前聊天室人數(shù):${wsSever.clients.size}`);
});

// 廣播任何客戶端發(fā)送的消息
ws.on("message", (data) => {
const msg = data.toString();
wsSever.clients.forEach((client) => {
client.send(msg);
});
});

// 當(dāng)有客戶端退出時(shí),廣播
ws.on("close", () => {
wsSever.clients.forEach((client) => {
client.send(`有人退出了聊天室,當(dāng)前聊天室人數(shù):${wsSever.clients.size}`);
});
});
});

每當(dāng)一個(gè)客戶端進(jìn)行了 websocket 連接,都會(huì)觸發(fā) wsServer 的 connection 事件,然后拿到一個(gè) ws 對(duì)象。

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

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

客戶端

客戶端使用原生的 WebSocket 對(duì)象,來(lái)和服務(wù)端進(jìn)行 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);
})

// 點(diǎn)擊發(fā)送按鈕,將輸入框中的內(nèi)容發(fā)送給服務(wù)器
const input = document.querySelector('input');
const btn = document.querySelector('button');
btn.onclick = () => {
ws.send(input.value);
input.value = '';
}

效果

簡(jiǎn)易聊天室

改為使用 Socket.IO

ws 庫(kù)是偏底層的實(shí)現(xiàn),比較簡(jiǎn)單。

另一個(gè)庫(kù) Socket.IO 的底層使用了 ws,并做功能上的增強(qiáng),提供更多的能力。

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

  1. 如果瀏覽器不支持 WebSocket,回退為 HTTP 長(zhǎng)輪詢方案來(lái)模擬 WebSocket( WebSocket 于 2011 年完成 RFC,已經(jīng)很久了,目前來(lái)說(shuō)主流瀏覽器都已經(jīng)支持 WebSocket 了,還不支持 WebSocket 的瀏覽器是屑)。
  2. 使用心跳包機(jī)制實(shí)現(xiàn)了自動(dòng)重連。
  3. 包緩存。斷連時(shí)發(fā)送數(shù)據(jù),會(huì)將數(shù)據(jù)保存下來(lái),等重新連接后再發(fā)送。
  4. 自定義事件支持。
  5. 廣播。

相比自己去一個(gè)個(gè)實(shí)現(xiàn),使用流行的輪子可能是更好的選擇。

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

服務(wù)端:

import { Server } from "socket.io";

// socket.io v3.x 開(kāi)始默認(rèn)不允許跨域,需要在配置顯式設(shè)置為允許跨域
const io = new Server(6060, { cors: { origin: "*" } });

io.on("connection", (socket) => {
// 新客戶端連接時(shí),廣播
io.emit("chat", `有人進(jìn)入聊天室,當(dāng)前聊天室人數(shù):${io.engine.clientsCount}`);

// 廣播任何客戶端發(fā)送的消息
socket.on("chat", (data) => {
io.emit("chat", data);
});

// 當(dāng)有客戶端退出時(shí),廣播
socket.on("disconnect", () => {
io.emit("chat", `有人退出了聊天室,當(dāng)前聊天室人數(shù):${io.engine.clientsCount}`);
});
});

需要特別注意的是,Socket.IO 的 v3.x 版本開(kāi)始,默認(rèn)不允許跨域,需要在配置顯式設(shè)置為允許跨域。

客戶端:

const socket = io('ws://localhost:6060');

socket.on('chat', (data) => {
const div = document.createElement('div');
div.innerText = data;
document.body.append(div);
})

// 點(diǎn)擊發(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 = '';
}

Socket.IO 優(yōu)點(diǎn)是實(shí)現(xiàn)了生產(chǎn)環(huán)境需要的底層非業(yè)務(wù)能力,讓我們能更心無(wú)旁騖地去編寫(xiě)業(yè)務(wù)代碼。

缺點(diǎn)是丟失了靈活性。因?yàn)樽隽硕ㄖ苹孕枰涮资褂?Socket.IO 的客戶端和服務(wù)端庫(kù)的包,某種意義脫離了網(wǎng)絡(luò)協(xié)議標(biāo)準(zhǔn)。在出現(xiàn)跨語(yǔ)言(比如前端是 JS,后端是 Java)的場(chǎng)景時(shí),需要提供對(duì)應(yīng)的語(yǔ)言的 Socket.IO 實(shí)現(xiàn)。

demo

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

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

結(jié)尾

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


分享題目:WebSocket入門(mén):簡(jiǎn)易聊天室
地址分享:http://www.dlmjj.cn/article/cddcepd.html