日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区

您的位置:首頁技術文章
文章詳情頁

如何用JS WebSocket實現簡單聊天

瀏覽:251日期:2024-03-27 17:57:59
短輪詢(Polling)

短輪詢的實現思路就是瀏覽器端每隔幾秒鐘向服務器端發送 HTTP 請求,服務端在收到請求后,不論是否有數據更新,都直接進行響應。在服務端響應完成,就會關閉這個 TCP 連接,代碼實現也最簡單,就是利用 XHR, 通過 setInterval 定時向后端發送請求,以獲取最新的數據。

setInterval(function() { fetch(url).then((res) => { // success code })}, 3000);

優點:實現簡單。

缺點:會造成數據在一小段時間內不同步和大量無效的請求,安全性差、浪費資源。

長輪詢(Long-Polling)

客戶端發送請求后服務器端不會立即返回數據,服務器端會阻塞請求連接不會立即斷開,直到服務器端有數據更新或者是連接超時才返回,客戶端才再次發出請求新建連接、如此反復從而獲取最新數據。大致效果如下:

如何用JS WebSocket實現簡單聊天

客戶端代碼如下:

function async() { fetch(url).then((res) => {async();// success code }).catch(() => {// 超時async(); })}

優點:比 Polling 做了優化,有較好的時效性。

缺點:保持連接掛起會消耗資源,服務器沒有返回有效數據,程序超時。

WebSocket

前面提到的短輪詢(Polling)和長輪詢(Long-Polling), 都是先由客戶端發起 Ajax 請求,才能進行通信,走的是 HTTP 協議,服務器端無法主動向客戶端推送信息。

當出現類似體育賽事、聊天室、實時位置之類的場景時,輪詢就顯得十分低效和浪費資源,因為要不斷發送請求,連接服務器。WebSocket 的出現,讓服務器端可以主動向客戶端發送信息,使得瀏覽器具備了實時雙向通信的能力。

沒用過 WebSocket 的人,可能會以為它是個什么高深的技術。其實不然,WebSocket 常用的 API 不多也很容易掌握,不過在介紹如何使用之前,讓我們先看看它的通信原理。

通信原理

當客戶端要和服務端建立 WebSocket 連接時,在客戶端和服務器的握手過程中,客戶端首先會向服務端發送一個 HTTP 請求,包含一個 Upgrade 請求頭來告知服務端客戶端想要建立一個 WebSocket 連接。

在客戶端建立一個 WebSocket 連接非常簡單:

let ws = new WebSocket(’ws://localhost:9000’);

類似于 HTTP 和 HTTPS,ws 相對應的也有 wss 用以建立安全連接,本地已 ws 為例。這時的請求頭如下:

Accept-Encoding: gzip, deflate, brAccept-Language: zh-CN,zh;q=0.9Cache-Control: no-cacheConnection: Upgrade // 表示該連接要升級協議Cookie: _hjMinimizedPolls=358479; ts_uid=7852621249; CNZZDATA1259303436=1218855313-1548914234-%7C1564625892; csrfToken=DPb4RhmGQfPCZnYzUCCOOade; jsESSIONID=67376239124B4355F75F1FC87C059F8D; _hjid=3f7157b6-1aa0-4d5c-ab9a-45eab1e6941e; acw_tc=76b20ff415689655672128006e178b964c640d5a7952f7cb3c18ddf0064264Host: localhost:9000Origin: http://localhost:9000Pragma: no-cacheSec-WebSocket-Extensions: permessage-deflate; client_max_window_bitsSec-WebSocket-Key: 5fTJ1LTuh3RKjsJxydyifQ==// 與響應頭 Sec-WebSocket-Accept 相對應Sec-WebSocket-Version: 13 // 表示 websocket 協議的版本Upgrade: websocket // 表示要升級到 websocket 協議User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_0) AppleWebKit/537.36 (Khtml, like Gecko) Chrome/76.0.3809.132 Safari/537.36

響應頭如下:

Connection: UpgradeSec-WebSocket-Accept: ZUip34t+bCjhkvxxwhmdEOyx9hE=Upgrade: websocket

如何用JS WebSocket實現簡單聊天

此時響應行(General)中可以看到狀態碼 status code 是 101 Switching Protocols, 表示該連接已經從 HTTP 協議轉換為 WebSocket 通信協議。 轉換成功之后,該連接并沒有中斷,而是建立了一個全雙工通信,后續發送和接收消息都會走這個連接通道。

注意,請求頭中有個 Sec-WebSocket-Key 字段,和相應頭中的 Sec-WebSocket-Accept 是配套對應的,它的作用是提供了基本的防護,比如惡意的連接或者無效的連接。Sec-WebSocket-Key 是客戶端隨機生成的一個 base64 編碼,服務器會使用這個編碼,并根據一個固定的算法:

GUID = '258EAFA5-E914-47DA-95CA-C5AB0DC85B11'; // 一個固定的字符串accept = base64(sha1(key + GUID)); // key 就是 Sec-WebSocket-Key 值,accept 就是 Sec-WebSocket-Accept 值

其中 GUID 字符串是RFC6455官方定義的一個固定字符串,不得修改。

客戶端拿到服務端響應的 Sec-WebSocket-Accept 后,會拿自己之前生成的 Sec-WebSocket-Key 用相同算法算一次,如果匹配,則握手成功。然后判斷 HTTP Response 狀態碼是否為 101(切換協議),如果是,則建立連接,大功告成。

實現簡單單聊

下面來實現一個純文字消息類型的一對一聊天(單聊)功能,廢話不多說,直接上代碼,注意看注釋。

客戶端:

function connectWebsocket() { ws = new WebSocket(’ws://localhost:9000’); // 監聽連接成功 ws.onopen = () => {console.log(’連接服務端WebSocket成功’);ws.send(JSON.stringify(msgData)); // send 方法給服務端發送消息 }; // 監聽服務端消息(接收消息) ws.onmessage = (msg) => {let message = JSON.parse(msg.data);console.log(’收到的消息:’, message)elUl.innerhtml += `<li>小秋:${message.content}</li>`; }; // 監聽連接失敗 ws.onerror = () => {console.log(’連接失敗,正在重連...’);connectWebsocket(); }; // 監聽連接關閉 ws.onclose = () => {console.log(’連接關閉’); };};connectWebsocket();

從上面可以看到 WebSocket 實例的 API 很容易理解,簡單好用,通過 send() 方法可以發送消息,onmessage 事件用來接收消息,然后對消息進行處理顯示在頁面上。 當 onerror 事件(監聽連接失敗)觸發時,最好進行執行重連,以保持連接不中斷。

服務端 Node: (這里使用ws庫)

const path = require(’path’);const express = require(’express’);const app = express();const server = require(’http’).Server(app);const WebSocket = require(’ws’);const wss = new WebSocket.Server({ server: server });wss.on(’connection’, (ws) => { // 監聽客戶端發來的消息 ws.on(’message’, (message) => { console.log(wss.clients.size); let msgData = JSON.parse(message); if (msgData.type === ’open’) { // 初始連接時標識會話 ws.sessionId = `${msgData.fromUserId}-${msgData.toUserId}`; } else { let sessionId = `${msgData.toUserId}-${msgData.fromUserId}`; wss.clients.forEach(client => {if (client.sessionId === sessionId) { client.send(message); // 給對應的客戶端連接發送消息} }) } }) // 連接關閉 ws.on(’close’, () => { console.log(’連接關閉’); });});

同理,服務端也有對應的發送和接收的方法。完整示例代碼見這里

這樣瀏覽器和服務端就可以愉快的發送消息了,效果如下:

如何用JS WebSocket實現簡單聊天

其中綠色箭頭表示發出的消息,紅色箭頭表示收到的消息。

心跳保活

在實際使用 WebSocket 中,長時間不通消息可能會出現一些連接不穩定的情況,這些未知情況導致的連接中斷會影響客戶端與服務端之前的通信,

為了防止這種的情況的出現,有一種心跳保活的方法:客戶端就像心跳一樣每隔固定的時間發送一次 ping,來告訴服務器,我還活著,而服務器也會返回 pong,來告訴客戶端,服務器還活著。ping/pong 其實是一條與業務無關的假消息,也稱為心跳包。

可以在連接成功之后,每隔一個固定時間發送心跳包,比如 60s:

setInterval(() => { ws.send(’這是一條心跳包消息’);}, 60000)總結

如何用JS WebSocket實現簡單聊天

通過上面的介紹,大家應該對 WebSocket 有了一定認識,其實并不神秘,這里對文章內容簡單總結一下。當創建 WebSocket 實例的時候,會發一個 HTTP 請求,請求報文中有個特殊的字段 Upgrade,然后這個連接會由 HTTP 協議轉換為 WebSocket 協議,這樣客戶端和服務端建立了全雙工通信,通過 WebSocket 的 send 方法和 onmessage 事件就可以通過這條通信連接交換信息。

以上就是如何用JS WebSocket實現簡單聊天的詳細內容,更多關于WebSocket的資料請關注好吧啦網其它相關文章!

標簽: JavaScript
相關文章:
日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
五月激情久久| 日本午夜精品视频在线观看| 成人精品久久| 精品久久精品| 久久久免费人体| 免费一级欧美片在线观看网站| 国产精品magnet| 久久久免费人体| 国产在线看片免费视频在线观看| 成人国产精品一区二区网站| 国产精品蜜芽在线观看| 国内揄拍国内精品久久| 麻豆国产精品视频| 精品三区视频| 肉色欧美久久久久久久免费看| 麻豆网站免费在线观看| 嫩草伊人久久精品少妇av杨幂| 久久97视频| 日本不卡视频一二三区| 国产乱人伦丫前精品视频| 美女久久久久久| 国产自产自拍视频在线观看| 99久久夜色精品国产亚洲狼| 7m精品国产导航在线| 国产一区丝袜| 欧美日韩在线播放视频| 男女性色大片免费观看一区二区 | 亚洲精品看片| 日韩动漫一区| 国语精品一区| 欧美日韩国产高清| 日韩va亚洲va欧美va久久| 欧美激情一区| 免费污视频在线一区| 最新国产拍偷乱拍精品| 91亚洲精品在看在线观看高清| 麻豆精品少妇| 久久久久91| 免费国产亚洲视频| 国产精品一区二区99| 日韩在线第七页| 久久性天堂网| 精品伊人久久| 午夜国产欧美理论在线播放| 日韩二区在线观看| 久久九九电影| 91成人精品在线| 99久久亚洲精品蜜臀| 日韩精品视频在线看| 精品国产免费人成网站| 中文精品电影| 激情视频网站在线播放色| 亚洲一区二区小说| 成人台湾亚洲精品一区二区| 9色国产精品| 国产精品毛片aⅴ一区二区三区| 肉色欧美久久久久久久免费看| 亚洲人成精品久久久| 荡女精品导航| 久久国产66| 国产精品精品国产一区二区| 国产精品三上| 激情久久一区二区| 亚洲日韩中文字幕一区| 久久久久久一区二区| 亚洲精品一二三**| 亚洲成人不卡| 国产精选久久| 亚洲一区二区网站| 国产成人精品一区二区免费看京| 免费在线观看视频一区| 成人污污视频| 日韩成人午夜精品| 99久久久久国产精品| 国产精品xxx| 丝瓜av网站精品一区二区| 天堂√8在线中文| 国产剧情一区二区在线观看| 日韩在线播放一区二区| 欧美一区二区三区高清视频| 久久精品国产99国产精品| 亚洲91网站| 婷婷综合网站| 激情国产在线| 美女精品视频在线| 日本成人一区二区| 亚洲激情av| 色婷婷久久久| 欧美亚洲tv| 日韩中文字幕不卡| 亚洲欧美日韩高清在线| 亚洲综合在线电影| 精品国产午夜| 欧美日韩一区二区高清| 老色鬼久久亚洲一区二区| 日韩欧美少妇| 国际精品欧美精品| 另类小说一区二区三区| 国产日韩高清一区二区三区在线| 欧美中文字幕| 欧美在线影院| 久久国产亚洲| sm捆绑调教国产免费网站在线观看 | 国产传媒在线观看| 国产精品入口久久| 日韩中文字幕一区二区高清99| 亚洲第一精品影视| 天堂а√在线最新版中文在线| 牛牛精品成人免费视频| 国产亚洲一区二区三区不卡| 亚洲免费一区三区| 国产精品毛片在线| 久久不射中文字幕| 日韩视频不卡| 99视频精品全国免费| 久久久久久久久丰满| 久久婷婷av| 91精品亚洲| 黄色不卡一区| 在线精品视频在线观看高清| 精品一区免费| 中文一区二区| 午夜亚洲一区| 国产精品日本欧美一区二区三区| 日韩视频在线一区二区三区 | 国产精品亚洲综合久久| 国产精品中文字幕制服诱惑| 国产精品一区二区免费福利视频| 欧美日韩99| 欧美视频一区| 国产精品tv| 丰满少妇一区| 日本欧美不卡| 悠悠资源网久久精品| 影音先锋国产精品| 免费黄网站欧美| 日本视频一区二区| 欧美一级一区| 精品淫伦v久久水蜜桃| 福利一区二区免费视频| 麻豆精品蜜桃| 婷婷色综合网| 婷婷亚洲成人| 亚洲激情二区| 好看的亚洲午夜视频在线| 日韩欧美精品| 成人精品天堂一区二区三区| 99久久亚洲精品蜜臀| 亚洲精品123区| 国产精品视区| 日韩中文字幕在线一区| 国产精品对白久久久久粗| 精品99在线| 亚洲五月婷婷| 亚洲免费网址| 亚洲不卡视频| 欧美精品aa| 丁香六月综合| 99国产精品| 久久狠狠久久| 日韩精品永久网址| 亚洲精品一区二区妖精| 午夜久久av| 精品一区不卡| 日韩天堂在线| 美国三级日本三级久久99| 国产欧美日韩精品高清二区综合区| 精品一区二区三区中文字幕| 国产综合激情| 亚洲深夜福利在线观看| 日韩中文字幕不卡| 日韩黄色免费网站| 欧美精品99| 欧美日韩国产传媒| 日韩av一二三| 欧美日韩国产v| 综合视频一区| 久久免费福利| 日韩一区二区免费看| 综合亚洲自拍| 精品久久福利| 图片区亚洲欧美小说区| 国产日本久久| 久久狠狠婷婷| 日本精品另类| 日韩欧美国产精品综合嫩v| 香蕉久久一区| 国产aa精品| 亚洲图片久久| 日本а中文在线天堂| 中文字幕一区二区三区日韩精品| 免费亚洲一区| 在线精品观看| 中文另类视频| 日本精品一区二区三区在线观看视频| 水蜜桃久久夜色精品一区| 亚洲理论在线| 久久精品国产68国产精品亚洲| 国产毛片精品| 日本午夜精品视频在线观看|