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

您的位置:首頁技術(shù)文章
文章詳情頁

JS如何實現(xiàn)基于websocket的多端橋接平臺

瀏覽:219日期:2024-03-25 17:53:24
目錄1. 要調(diào)試什么2. websocket 的特性3. 建立 socket 連接3.1 如何創(chuàng)建房間3.2 客戶端的斷線重現(xiàn)機制3.3 心跳檢測4. 進行接口的調(diào)試4.1 接口的調(diào)試4.2 歷史記錄的存儲5. 新聞客戶端內(nèi) jsapi 的調(diào)試6. 總結(jié)6.1 為什么要手動輸入 serverId6.2 如何保證一個客戶端的 socket 請求都進入到同一個進程中6.3 多進程之間的通信1. 要調(diào)試什么

我們主要要知道調(diào)試什么,最終回去到什么樣子的結(jié)果:

1.調(diào)試接口,傳入接口地址,即可獲取對應(yīng)的結(jié)果;并且可以同時調(diào)試多個設(shè)備;

2.調(diào)試 jsapi,輸入對應(yīng)的方法,則即可在新聞客戶端中展示出效果。

在調(diào)試接口方面,其實我們有一種方法可以方便地進行調(diào)試,但有兩個限制條件:Android系統(tǒng)和測試版的客戶端,這樣通過 Chrome 瀏覽器進行橋接。但這種方式,在 iOS 系統(tǒng)和正式版的客戶端中,就失效了。

2. websocket 的特性

WebSocket 協(xié)議的最大特點就是,服務(wù)器可以主動向客戶端推送信息,客戶端也可以主動向服務(wù)器發(fā)送信息,是真正的雙向平等對話,屬于服務(wù)器推送技術(shù)的一種。

JS如何實現(xiàn)基于websocket的多端橋接平臺

其他特點包括:

1.建立在 TCP 協(xié)議之上,服務(wù)器端的實現(xiàn)比較容易。

2.與 HTTP 協(xié)議有著良好的兼容性。默認端口也是 80 和 443,并且握手階段采用 HTTP 協(xié)議,因此握手時不容易屏蔽,能通過各種 HTTP 代理服務(wù)器。

3.數(shù)據(jù)格式比較輕量,性能開銷小,通信高效。

4.可以發(fā)送文本,也可以發(fā)送二進制數(shù)據(jù)。

5.沒有同源限制,客戶端可以與任意服務(wù)器通信。

6.協(xié)議標識符是 ws(如果加密,則為 wss),服務(wù)器網(wǎng)址就是 URL。

3. 建立 socket 連接

為了滿足我們在第 1 部分設(shè)置的調(diào)試目標,我們這里要實現(xiàn)的功能有:

1.PC 端相當(dāng)于房主,建立房間后,其他設(shè)備可以進入到該房間,一個設(shè)備只能進入到一個房間中;

2.客戶端有斷線重連的機制,當(dāng)客戶端斷開連接后,可以嘗試重連;

3.服務(wù)端維護一個心跳檢測的機制,當(dāng)有新設(shè)備進入或者之前的設(shè)備退出時,要及時地更新當(dāng)前房間中的設(shè)備列表;

3.1 如何創(chuàng)建房間

在瀏覽器上輸入房間的標識,若瀏覽器與服務(wù)端成功建立起 websocket 連接后,則在瀏覽器端創(chuàng)建對應(yīng)的二維碼。用微信/手 Q 或者其他掃描二維碼的設(shè)備進行掃描,即可通過提前設(shè)定的 scheme 協(xié)議,跳轉(zhuǎn)到新聞客戶端里對應(yīng)的調(diào)試頁面。

若客戶端里也與服務(wù)端成功建立 websocket 連接后,則相當(dāng)于進入房間成功,PC 端會出現(xiàn)一個對應(yīng)的圖標。

ws.open(serverId) .then(() => {// PC 端成功建立連接后setStatus('linked'); // 更新頁面的狀態(tài)// 生成二維碼qrcode(`/tools/index.html#/newslist?serverId=${serverId}`).then(url => { setCodeUrl(url);}); }) .catch(e => {// 建立連接失敗console.error(e);Modal.error({ title: '當(dāng)前服務(wù)器出現(xiàn)問題啦,正在搶修中' });setStatus('unlink'); });3.2 客戶端的斷線重現(xiàn)機制

在移動端中的頁面有個特點,當(dāng)屏幕黑屏后,或者因為其他的原因,客戶端會自動斷開 socket 連接。

為了方便進行調(diào)試,而不是每次在斷開連接后,需要手動點擊,或者重新進入頁面。我在這里實現(xiàn)了一個簡單的斷線重連機制。websocket 連接斷開時,會執(zhí)行onclose的回調(diào),因此,我們可以在 onclose 事件中進行再次重連的機制。

同時,為了防止無限制的重連嘗試,我在這里也進行了下限制,最多重連 3 次,3 次后還沒有重新連接上,則停止連接;若重連成功,則將重連次數(shù)重置為 3。

斷開連接時:

// 斷開連接時ws.onclose(() => { timer = setTimeout(() => {setStatus('unlink');setCodeUrl(''); }, 500); reconnectNum--; // 限制重連的次數(shù) if (reconnectNum >= 0) {_open(); // 嘗試重新連接 }});

連接成功時:

ws.open(serverId).then(() => { // PC 端成功建立連接后 +reconnectNum = 3; +timer && clearTimeout(timer); setStatus('linked'); // 更新頁面的狀態(tài) // 生成二維碼 qrcode(`/tools/index.html#/newslist?serverId=${serverId}`).then(url => {setCodeUrl(url); });});3.3 心跳檢測

就像我們在 QQ 群里聊天一樣,哪個人在線要一目了然,若有人進入到聊天群,或者有人退出了,都要通知房主,并及時地更新群列表。

心跳檢測主要有 2 種方式:客戶端發(fā)起的心跳檢測和服務(wù)端維護的心跳檢測。我們稍微講解下這兩種:

1.客戶端發(fā)起的心跳:每隔一段固定的時間,向服務(wù)器端發(fā)送一個 ping 數(shù)據(jù),如果在正常的情況下,服務(wù)器會返回一個 pong 給客戶端,如果客戶端通過 onmessage 事件能監(jiān)聽到的話,說明請求正常。

2.服務(wù)端維護的心跳:每隔一段時間,檢測所有連接的狀態(tài),若狀態(tài)為斷開時,則將其從列表中剔除。

我在這里使用的是服務(wù)端維護的心跳檢測,當(dāng)房間里的設(shè)備數(shù)量發(fā)生變化時,則服務(wù)端向客戶端推送最新的設(shè)備列表:

// 持續(xù)監(jiān)測客戶端的連接狀態(tài)// 若已斷開連接,則將客戶端清除let aliveClients = new Map();let lastAliveLength = new Map();setInterval(() => { let clients = {}; wss.clients.forEach(function each(ws) {if (ws.isAlive === false) { return ws.terminate();}const serverId = ws.serverId;if (clients[serverId]) { clients[serverId].push(ws);} else { clients[serverId] = [ws];}ws.isAlive = false;ws.ping(() => {}); }); for (let serverId in clients) {aliveClients.set(serverId, clients[serverId]);const length = clients[serverId].length;// 若當(dāng)前serverId連接的設(shè)備數(shù)量發(fā)生變化,則發(fā)送消息if (length !== lastAliveLength.get(serverId)) { // 想當(dāng)前所有serverId的設(shè)備發(fā)送消息 sendAll('devices', clients[serverId], serverId); // 存儲上次當(dāng)前serverId的連接數(shù) lastAliveLength.set(serverId, length);} } const size = wss.clients.size; console.log('connection num: ', size, new Date().toTimeString());}, 2000);4. 進行接口的調(diào)試

我們在第 3 節(jié)已經(jīng)成功把 PC 端和新聞客戶端連接起來了,那么怎么進行雙端數(shù)據(jù)的通信?

4.1 接口的調(diào)試

我們在這里要傳入 3 個字段:

1.serverId: 即房間號,服務(wù)端要將信息廣播給所有帶有 serverId 的成員;

2.type: 類型,這條指令是要做什么的;

3.msg: 傳入的參數(shù);

在接口調(diào)試的過程中,則傳入的參數(shù)是:

const params = { type: 'post', // 類型 msg: {// 參數(shù)url: 'https://api.prize.qq.com/v1/newsapp/answer/share/oneQ?qID=506336' }};

當(dāng)客戶端正常完成接口的請求后,則將接口結(jié)果、cookie 和設(shè)備信息等返回到 PC 端:

// 請求的方法const post = url => { if (window.TencentNews && window.TencentNews.post) {window.TencentNews.post(url, {}, window[id], { loginType: 'qqorweixin' }, {}); } else if (window.TencentNews && window.TencentNews.postData) {window.TencentNews.postData(url, ’{'a':'b'}’, id, 'requestErrorCallback'); }};// 移動端向服務(wù)端發(fā)起的數(shù)據(jù)ws.send({ type: 'postCb', // 執(zhí)行的結(jié)果 msg: {method: 'post',result,cookie: document.cookie,appInfo }});

這樣就能在前端展示出結(jié)果了,而且是真實的數(shù)據(jù)請求。

4.2 歷史記錄的存儲

歷史記錄這塊,我們周邊的同學(xué)在試用的過程中,還是非常迫切需要的需求。要不然每次要測試之前的接口地址時,都需要重新輸入或者粘貼,非常不方便。

我們把用戶請求的 URL、返回的結(jié)果、cookie、設(shè)備信息等比較完整的信息存儲到 boss 中,而本地只存儲歷史的 URL,當(dāng)用戶需要再次測試之前的接口時,點擊一下即可。若需要查看之前調(diào)試的接口,可以去鷹眼上進行查看。

JS如何實現(xiàn)基于websocket的多端橋接平臺

本地采用的是localStorage的方式進行存儲。還有更重要的是,我們也使用mobx的響應(yīng)式工具,能夠在用戶完成這次請求后,馬上在側(cè)邊的歷史記錄里看到結(jié)果。

5. 新聞客戶端內(nèi) jsapi 的調(diào)試

除了可以調(diào)試接口外,還可以進行一些新聞客戶端內(nèi)的 jsapi 調(diào)試。我們新聞客戶端的 jsapi 有兩種調(diào)用的方式:

// 直接調(diào)用window.TencentNews.login('qqorweixin', isLogined => console.log(isLogined));// invoke方式調(diào)用window.TencentNews.invoke('login', 'qqorweixin', isLogined => console.log(isLogined));

這里我選擇了使用invoke的方式來調(diào)用 jsapi。

PC 端發(fā)起 jsapi 的調(diào)用:

ws.send({ type: 'call', msg: {method: method,params: slice.call(arguments) }});

移動端在收到服務(wù)端發(fā)過來的請求后,進行 jsapi 的調(diào)用,并將執(zhí)行的結(jié)果返回到 PC 端即可:

JS如何實現(xiàn)基于websocket的多端橋接平臺

const handleNewsApi = async (msg: any): Promise<any> => { await tencentReady(); const { method, params } = msg; return new Promise(resolve => {window.TencentNews.invoke(method, ...params, (result: any) => { resolve({ method, result });}); });};6. 總結(jié)

到這里,我的“基于 websocket 的多端橋接平臺”基本上已經(jīng)構(gòu)建完畢了。不過還是有 2 個問題要簡要的說明下。

6.1 為什么要手動輸入 serverId

最開始想著用戶創(chuàng)建房間時,由系統(tǒng)隨機產(chǎn)生一個 uuid,但后來想,如果用戶刷新頁面了,這個 uuid 就會發(fā)生變化,導(dǎo)致無法連接到之前的 uuid,所以這里就換成了手動輸入。

6.2 如何保證一個客戶端的 socket 請求都進入到同一個進程中

當(dāng)我們后臺采用多個進程時,若用戶的請求我們不做干預(yù),會造成請求的隨機訪問,產(chǎn)生 400 的請求,畢竟最開始連接在 A 進程中,現(xiàn)在發(fā)起的請求到 B 進程中,B 進程不知道怎么處理了。

這里有多種方式可以進行處理:

方法 介紹 優(yōu)點 缺點 一致性 hash 算法 所有的主機和連接都分配到 0 ~ 2^32-1 的虛擬圓中 1. 適用在大規(guī)模的應(yīng)用; 2. 某個主機或者進程掛掉后,影響小 實現(xiàn)比較復(fù)雜 nginx 分配 自帶的 ip_hash 可實現(xiàn)負載均衡; 同一 ip 會被分配給固定的后端服務(wù)器 配置方便 可能會集中到某個進程中

我這里的平臺是內(nèi)部的調(diào)試平臺,用戶量不大,殺雞焉用牛刀,而且我們只有一臺機器,因此我們考慮的是同一個 IP 進入到同一個進程中。這里我借用里 nginx 中的 ip_hash 思想:當(dāng)請求來到主進程后,我這里對 IP 進行加權(quán)計算后,然后按照進程的個數(shù)進行取模。

顯然這種方式也有可能存在一個進程中 socket 連接過多的問題,不過在用戶量不多的時候完全可以接受(針對這個問題我也考慮了別的方法,例如瀑布流的方式,每次給子進程分配連接的時候,都首先獲取到連接數(shù)最少的那個進程,然后連接分配給這個進程,不過還要維護一個表,每次都要計算)。

6.3 多進程之間的通信

同一個房間里,當(dāng) PC 端的 socket 連接和多個移動端的連接不在同一個進程中時,就會存在跨進程的問題。一個極端的例子,每個 socket 連接都在不同的進程中,那么就要考慮如何通知其他的進程,需要給客戶端發(fā)送請求了。

比較簡單的方式利用我們的機制,每個 PC 端的用戶就是房主,可以創(chuàng)建一個房間,移動設(shè)備就是房間中的成員,每個房間都是獨立的,互不干擾。這樣我們把房間里所有的 socket 連接,通過房間的標識,都放到同一個進程中,這樣就沒有跨進程的問題了。但這種方式存在的一個問題是:一個房間里的連接過多時,都需要這同一個進程來承擔(dān),而別的進程卻閑著的。

還有可以使用 redis:利用 redis 的發(fā)布/訂閱者模式,將當(dāng)前進程中的房間標識和信息廣播到其他的進程中,其他進程中有相同房間標識的 socket 連接,進行相應(yīng)的操作。

以上就是JS如何實現(xiàn)基于websocket的多端橋接平臺的詳細內(nèi)容,更多關(guān)于JS基于websocket的多端橋接平臺的資料請關(guān)注好吧啦網(wǎng)其它相關(guān)文章!

標簽: JavaScript
相關(guān)文章:
日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
色在线视频观看| 欧美日韩国产在线观看网站| 亚洲欧美高清| 日韩伦理一区| 日本精品影院| 91精品一区二区三区综合| 激情黄产视频在线免费观看| 国产美女久久| 亚洲特级毛片| 亚洲人成精品久久久| 国产91精品对白在线播放| 国产高清亚洲| 国产精品1区| 欧美日韩中文字幕一区二区三区| 欧美成人高清| 国产探花在线精品一区二区| 红杏一区二区三区| 国产精品一区二区av交换| 视频一区中文字幕精品| 日本欧美在线| 国产精品极品| 九九99久久精品在免费线bt| av中文字幕在线观看第一页| 欧美羞羞视频| 好吊日精品视频| 四虎精品永久免费| 日本a口亚洲| 精品国产午夜肉伦伦影院| 日韩欧美一区免费| 红桃视频欧美| 日韩精品福利一区二区三区| 美女精品一区二区| 久久久一二三| 免费高清在线一区| 国产精品一区二区三区美女| 亚洲人成在线网站| 亚洲一区二区小说| 免费一级欧美在线观看视频| 亚洲综合电影| 日韩影院免费视频| 国产一区 二区| 日韩精品欧美| 在线一区二区三区视频| 久久av网站| 91精品国产自产在线观看永久∴| 国产精品美女| 亚洲一区日韩在线| 免费在线观看视频一区| 国产午夜精品一区二区三区欧美| 日本91福利区| 男女性色大片免费观看一区二区 | 欧洲一级精品| 亚洲va在线| 亚洲3区在线| 久久影院午夜精品| 免费人成精品欧美精品| 日韩欧美中文字幕一区二区三区| 久久免费福利| 欧美理论视频| 91精品国产自产精品男人的天堂 | 国产综合精品| 日本aⅴ亚洲精品中文乱码| 日韩中文字幕高清在线观看| 亚洲色图综合| av高清不卡| 综合亚洲视频| 日韩高清中文字幕一区二区| 四虎国产精品免费久久| 在线亚洲人成| 亚洲人成毛片在线播放女女| 亚洲天堂资源| 91精品视频一区二区| 91精品蜜臀一区二区三区在线| 国产一卡不卡| 99国产精品视频免费观看一公开| 精品亚洲精品| 日韩国产欧美一区二区三区| 成人精品亚洲| 国产精品调教视频| 日韩在线黄色| 在线日韩一区| 97久久亚洲| 日韩精品成人| 国产日韩一区| 蜜桃精品视频| 久久久久国产一区二区| 日韩精品五月天| 韩国女主播一区二区三区| 99国产精品| 97久久中文字幕| 亚洲少妇自拍| 久久国产免费| 国产精品不卡| 国产日韩三级| 亚洲狼人精品一区二区三区| 亚洲欧美一区在线| 理论片午夜视频在线观看| 国产精品成人**免费视频| 伊人久久大香伊蕉在人线观看热v| 日韩精品dvd| 精品黄色一级片| 国产精品115| 国产精品亚洲四区在线观看| 日本中文字幕不卡| 中文字幕成人| 一区二区三区午夜视频| 亚洲欧美日韩综合国产aⅴ| 久久在线免费| 久久裸体视频| 四虎884aa成人精品最新| 久久久久久自在自线| 久久精品国产久精国产爱| 欧美精品国产白浆久久久久| 亚洲狼人精品一区二区三区| 亚洲一区日韩| 国产精品丝袜xxxxxxx| 五月天久久网站| 激情久久婷婷| 久久国产中文字幕| 日韩中文在线电影| 日本综合字幕| 欧美日韩视频网站| 国产麻豆精品| 国产经典一区| 久久午夜影视| 极品av在线| 久久九九国产| 99免费精品| 亚洲深夜av| 亚洲精品黄色| 伊人精品久久| 欧美日韩国产在线观看网站| 国产精品扒开腿做爽爽爽软件| 蜜臀va亚洲va欧美va天堂 | 国产精品福利在线观看播放| 麻豆精品新av中文字幕| 国产精品极品国产中出| 久久香蕉网站| 国产一区二区三区四区二区| www在线观看黄色| 99久久精品国产亚洲精品| 不卡在线一区| 亚洲国产专区校园欧美| 亚洲国产不卡| 亚洲91网站| 国产精品白丝一区二区三区| 国产videos久久| 亚洲不卡av不卡一区二区| 狠狠干成人综合网| 亚洲精品无吗| 久久尤物视频| 99精品视频在线观看免费播放| 91成人精品| 日韩欧美高清一区二区三区| 美女视频一区在线观看| 日韩在线第七页| 久久亚洲电影| 久久国产麻豆精品| 在线天堂中文资源最新版| 国产真实久久| 日韩精品久久久久久| 精品免费视频| 欧美日韩国产亚洲一区| 日韩中文字幕| 国产成人久久精品一区二区三区| 日韩在线观看不卡| 国产日韩亚洲欧美精品| 亚洲伊人精品酒店| 婷婷色综合网| 亚欧洲精品视频在线观看| 88xx成人免费观看视频库| 日本精品一区二区三区在线观看视频| 欧美日韩一区二区国产| 亚洲不卡av不卡一区二区| 欧美激情另类| 国产精品2区| 亚洲国产成人精品女人| 青青草91视频| 日韩大片在线播放| 丝袜诱惑制服诱惑色一区在线观看| 日本va欧美va瓶| 国精品产品一区| 国产精品日韩| 久久精品国产99| 亚洲精品a级片| 国产毛片久久久| 美女福利一区二区三区| 黄色av一区| 国产精品久久久网站| 久久精品青草| 欧美日韩va| 国户精品久久久久久久久久久不卡| 日本不卡一区二区三区| 久久激情一区| 国产精品亚洲人成在99www| 欧美网站在线| 国产一区二区三区久久| 亚洲综合二区| 国产成人精品一区二区三区视频| 男女男精品网站|