99精品久久精品一区二区-亚洲熟妇无码?v在线播放-日本国产精品无码字幕在线观看-久久久亚洲永夜AV-亚洲一级无码一区二区一-免费国产成高清人在线视频-中文字幕乱码免费观看-国产毛片精品妇女久久久

ARTICLE DETAIL

資訊詳情

深耕商務(wù)建站與企業(yè)官網(wǎng)運(yùn)營的一線實(shí)戰(zhàn)洞察。

基于WebSocket的多端實(shí)時(shí)通信實(shí)戰(zhàn):連接管理、心跳與消息路由

基于WebSocket的多端實(shí)時(shí)通信實(shí)戰(zhàn):連接管理、心跳與消息路由 簡介基于WebSocket的LAS多端互通畢業(yè)設(shè)計(jì)項(xiàng)目面向需要實(shí)現(xiàn)實(shí)時(shí)位置感知與多端數(shù)據(jù)同步的開發(fā)者重點(diǎn)解決傳統(tǒng)HTTP只能請求/響應(yīng)、無法主動推送導(dǎo)致的位置信息滯后問題。壓縮包共55個文件包含46個Python源碼文件、7張JPG效果圖、1個Markdown說明文檔及License文件整體僅485KB輕量而完整。項(xiàng)目采用服務(wù)端集中轉(zhuǎn)發(fā)與客戶端異步接入的方式并配有插件化模塊設(shè)計(jì)覆蓋聊天橋接、在線玩家查詢、簽到、坐標(biāo)共享等典型場景源碼對服務(wù)端、客戶端、插件邏輯做了清晰劃分JPG預(yù)覽圖可直觀對照運(yùn)行效果便于快速理解WebSocket雙向通信在LAS系統(tǒng)中的應(yīng)用機(jī)制。目前已有38人學(xué)習(xí)參考適合作為畢業(yè)設(shè)計(jì)參考或課程項(xiàng)目拓展也可在讀懂核心流程后自行擴(kuò)展消息類型與前端交互界面尤其能體現(xiàn)對通信協(xié)議與工程結(jié)構(gòu)的綜合運(yùn)用。1. 基于WebSocket的LAS多端互通先說清楚這東西解決什么中午改完桌面端的排班模板手機(jī)上的小程序要能立刻看到新狀態(tài)而不是等用戶手動刷新或者輪詢兜底。這就是LAS多端互通最典型的場景一套業(yè)務(wù)服務(wù)同時(shí)掛了桌面端、手機(jī)端、網(wǎng)頁端任何一端產(chǎn)生變化其它端要在秒級內(nèi)感知到。傳統(tǒng)HTTP做不到實(shí)時(shí)下行推送WebSocket長連接才是承擔(dān)這個角色的主干。標(biāo)題里的LAS在這里不是某個公開標(biāo)準(zhǔn)它就是一個業(yè)務(wù)代號你可以把它映射成你手頭任何一套需要多端協(xié)作的系統(tǒng)名?!富赪ebSocket的LAS多端互通.zip」拆開看就三件事用WebSocket建立長連接在連接之上做LAS業(yè)務(wù)消息的轉(zhuǎn)發(fā)再解決多端同時(shí)在線的身份識別與消息路由。比做一個單聊或通知推送復(fù)雜的地方在于同一個用戶可能同時(shí)在電腦瀏覽器、手機(jī)App、微信小程序里掛著服務(wù)端得知道一條消息該發(fā)給哪幾個連接哪些連接其實(shí)已經(jīng)死了以及消息發(fā)過去之后對方到底收沒收到。這篇筆記適合兩類人。一類是后端要接WebSocket但之前只寫過接口的能跟著把連接管理、心跳機(jī)制和消息路由跑起來另一類是前端要把網(wǎng)頁、小程序、桌面端接到同一套實(shí)時(shí)鏈路上的看完能知道服務(wù)端是怎么判定自己掉線的以及前端該怎么配合。下面所有代碼我都按Node.js的ws庫來寫這套方案換到Netty、Spring WebSocket或者Go的gorilla/websocket上思路是同一套。2. 連接管理是互通的底座把每個端變成可尋址的對象多端互通的第一步不是寫消息轉(zhuǎn)發(fā)而是先讓服務(wù)端能認(rèn)得出每一個連接。裸的WebSocket連接在服務(wù)端只是一個socket對象它不知道自己屬于哪個用戶、哪個端、在哪個房間。如果直接拿這個socket做消息收發(fā)你會很快發(fā)現(xiàn)代碼變成一團(tuán)亂麻要廣播的時(shí)候不知道發(fā)給誰用戶換設(shè)備登錄后舊連接也沒法處理。所以第一層要做的是給連接套上身份。2.1 為什么不能直接用裸連接來收發(fā)消息很多第一次接觸WebSocket的人會直接這樣寫connection事件里拿到socket然后往socket上綁onmessage收到什么轉(zhuǎn)發(fā)什么。單連接demo沒問題一旦出現(xiàn)「用戶A在手機(jī)上發(fā)一條消息他桌面端和網(wǎng)頁端也要同時(shí)收到」光有socket就不夠了因?yàn)榉?wù)端根本沒有「用戶」這個概念只有一堆不知道是誰的連接。LAS多端互通里最常見的狀態(tài)是一個用戶同時(shí)掛了三個連接三個連接的契約還可能不一樣——網(wǎng)頁端只關(guān)心排班變更桌面端還會同步模板文件手機(jī)端要收審批通知。你不能把這三類消息無差別群發(fā)給所有連接。所以必須在連接之上加一層會話Session抽象把「物理連接」和「邏輯身份」分開。連接斷開只會影響某個connId而用戶的多個連接之間是弱關(guān)聯(lián)其中一個掉了不應(yīng)該影響另外兩個繼續(xù)收消息。我一般會把連接生命周期里的注冊、心跳、鑒權(quán)、路由全部收口到一個ConnectionManager里業(yè)務(wù)層不直接碰ws對象。這樣做還有個好處將來把單機(jī)改成多實(shí)例部署時(shí)ConnectionManager內(nèi)部換成Redis維護(hù)連接索引業(yè)務(wù)代碼不用動。2.2 連接注冊clientId 與 connectionId 的雙層索引先定協(xié)議客戶端握手時(shí)在URL的query里帶clientId這個ID代表一個業(yè)務(wù)用戶由LAS自己的登錄態(tài)生成服務(wù)端每接受一條連接就生成一個全局唯一的connectionId。中間層維護(hù)三張表connMapconnectionId - WebSocket 實(shí)例用于直接發(fā)消息userMapclientId - Set 用于按用戶找到他所有的端roomMaproomId - Set 用于按房間做廣播。下面是最小可運(yùn)行的注冊邏輯// server.js —— WebSocket 連接注冊與用戶索引維護(hù) const { WebSocketServer } require(ws); const crypto require(crypto); const connMap new Map(); // connectionId - ws const userMap new Map(); // clientId - SetconnectionId // 用 wss 實(shí)例監(jiān)聽端口按 LAS 網(wǎng)關(guān)配置調(diào)整比如 8080 const wss new WebSocketServer({ port: 8080, maxPayload: 64 * 1024 * 1024 // 允許 64MB 單幀給文件類消息留余量 }); function parseClientId(url) { // 握手地址形如: /?clientIdU10086tokenxxx // 生產(chǎn)環(huán)境這里的 token 要做簽名校驗(yàn)不能用純明文 return new URLSearchParams(url.split(?)[1]).get(clientId); } wss.on(connection, (ws, req) { const connId crypto.randomUUID(); const clientId parseClientId(req.url); if (!clientId) { ws.close(4001, missing clientId); // 握手失敗直接斷開 return; } connMap.set(connId, ws); if (!userMap.has(clientId)) userMap.set(clientId, new Set()); userMap.get(clientId).add(connId); // 把 connId 掛到 ws 上后面 onmessage 里好取 ws.connId connId; ws.clientId clientId; ws.on(close, () { connMap.delete(connId); const conns userMap.get(clientId); if (conns) { conns.delete(connId); if (conns.size 0) userMap.delete(clientId); } }); });注冊這段邏輯里parseClientId 從握手URL解析業(yè)務(wù)用戶ID這個設(shè)計(jì)是故意的WebSocket 的握手就是一次普通HTTP請求可以把鑒權(quán)信息放進(jìn)query或header不要在建立連接之后再單獨(dú)發(fā)一條「登錄消息」——那樣會給中間層留下一個沒身份的空窗期。ws.close(4001, missing clientId) 是拒絕握手的標(biāo)準(zhǔn)姿勢客戶端會收到4001錯誤碼并觸發(fā)onclose便于前端區(qū)分「被拒」和「網(wǎng)絡(luò)斷開」。注意maxPayload這個參數(shù)。LAS如果涉及模板文件、簡報(bào)圖片甚至點(diǎn)云預(yù)覽單幀消息很容易超過默認(rèn)1MB上限。我按64MB開是給大數(shù)據(jù)量消息留余地但代價(jià)是內(nèi)存壓力增加業(yè)務(wù)不需要傳大文件時(shí)建議調(diào)回1MB~8MB。2.3 房間分組把廣播范圍圈出來多端互通不可能所有消息都發(fā)給所有人。LAS里典型的房間模型是「項(xiàng)目組」一個項(xiàng)目組的變更消息只需要推給這個組里的人跨組消息屬于越權(quán)。所以第三張表roomMap做的事就是把連接歸組。// room.js —— 房間管理基于 Set 做連接維度分組 const roomMap new Map(); // roomId - SetconnectionId function joinRoom(connId, roomId) { if (!roomMap.has(roomId)) roomMap.set(roomId, new Set()); roomMap.get(roomId).add(connId); } function leaveRoom(connId, roomId) { roomMap.get(roomId)?.delete(connId); } function broadcastToRoom(roomId, message) { const conns roomMap.get(roomId); if (!conns) return; const raw JSON.stringify(message); for (const connId of conns) { const ws connMap.get(connId); // readyState 1 表示連接處于 OPEN 狀態(tài)防止往 CLOSED 連接上寫 if (ws ws.readyState 1) ws.send(raw); } }這里有一個需要想清楚的點(diǎn)房間維度到底按clientId還是connectionId。我上面是按connectionId存的好處是一個用戶多個端在不同房間時(shí)互不干擾代價(jià)是用戶換房間要做兩次leaveRoomjoinRoom。如果你確定一個用戶所有端永遠(yuǎn)在同一個房間就按clientId存房間每次廣播時(shí)先展開成connectionId列表再發(fā)送省掉一部分重復(fù)消息。兩個方案都能跑選擇標(biāo)準(zhǔn)只有一個你的業(yè)務(wù)允不允許同一個人的兩個端處在不同項(xiàng)目組。3. WebSocket心跳機(jī)制實(shí)現(xiàn)服務(wù)端如何判斷「對方還活著」連接建立不等于連接健康。LAS多端互通里最常見的翻車現(xiàn)場是客戶端突然從4G切到Wi-FiTCP連接已經(jīng)死了但服務(wù)端和客戶端都沒有立刻感知服務(wù)端還往這個死連接上發(fā)消息客戶端一直收不到也不重連。要解決這個問題必須有一套心跳機(jī)制。這也是WebSocket長連接工程里最值得摳細(xì)節(jié)的部分。3.1 心跳機(jī)制實(shí)現(xiàn)為什么是服務(wù)端主動 ping 而不是讓客戶端表態(tài)網(wǎng)上很多方案是客戶端定時(shí)發(fā)一個{type:heartbeat}給服務(wù)端服務(wù)端收到就更新lastSeen。這種做法能用但它有個隱患客戶端的定時(shí)器和網(wǎng)絡(luò)棧是獨(dú)立的即使鏈路已經(jīng)半斷開客戶端的setInterval照樣觸發(fā)并調(diào)用ws.sendsend不報(bào)錯并不代表數(shù)據(jù)真的到了對端。標(biāo)準(zhǔn)做法是服務(wù)端用WebSocket協(xié)議層的ping/pong控制幀。ws庫的底層會自動響應(yīng)協(xié)議層的pong幀所以服務(wù)端只要定時(shí)ping然后統(tǒng)計(jì)這個周期內(nèi)有沒有收到pong就能精確知道TCP鏈路是否通著??刂茙蛔邩I(yè)務(wù)消息隊(duì)列比應(yīng)用層心跳更省資源、判定更準(zhǔn)。3.2 心跳代碼與參數(shù)間隔、誤判閾值、重連退避// heartbeat.js —— 基于 ws 庫的協(xié)議層心跳間隔 30s容忍 2 個周期無響應(yīng) const aliveSet new Set(); // 記錄“本周期內(nèi)回過 pong”的連接 wss.on(connection, (ws) { aliveSet.add(ws); ws.on(pong, () aliveSet.add(ws)); ws.on(close, () aliveSet.delete(ws)); }); const HEARTBEAT_INTERVAL 30_000; // 每 30s 檢查一輪 const HEARTBEAT_TIMEOUT 60_000; // 距離上一次 pong 超過 60s 視為死亡 setInterval(() { for (const ws of wss.clients) { if (ws.readyState ! ws.OPEN) { aliveSet.delete(ws); ws.terminate(); // 直接掐斷觸發(fā)客戶端重連 continue; } if (aliveSet.delete(ws)) { ws.ping(); // 本周期有 pong繼續(xù)探活 } else { // 上一周期沒收到 pong說明鏈路已經(jīng)斷了 ws.terminate(); } } }, HEARTBEAT_INTERVAL);這套邏輯的關(guān)鍵在aliveSet.delete(ws)的返回值每輪進(jìn)入定時(shí)器時(shí)如果這個連接在上一個周期內(nèi)回過pongdelete會返回true然后重新ping如果返回false說明這個連接已經(jīng)整整一個心跳周期沒有回應(yīng)直接terminate。terminate和close的區(qū)別值得注意close是禮貌地走完關(guān)閉握手但TCP層可能已經(jīng)死了close發(fā)不出去terminate是直接銷毀底層socket立刻生效。服務(wù)端探活發(fā)現(xiàn)死連接就一律用terminate。參數(shù)別拍腦袋。30秒的檢查間隔和60秒的容忍閾值適合絕大多數(shù)內(nèi)網(wǎng)和公網(wǎng)場景但如果你在弱網(wǎng)環(huán)境比如移動端經(jīng)常進(jìn)出電梯建議把間隔調(diào)到15秒容忍閾值保持2個周期不變。間隔太短會增加無謂的包量和CPU開銷太長則會讓用戶感知到「已斷線但重連遲遲不來」。另外服務(wù)端terminate之后不要馬上重連——客戶端收到onclose再發(fā)起重連這才是合理鏈路服務(wù)端不要替客戶端做重連決定。參數(shù)建議值說明HEARTBEAT_INTERVAL30s弱網(wǎng) 15s兩次 ping 的間隔HEARTBEAT_TIMEOUT2 × interval連續(xù)兩個周期無 pong 判定死亡服務(wù)端斷開方式terminate不依賴 TCP 層狀態(tài)直接銷毀客戶端重連退避1s → 5s → 15s → 30s 封頂指數(shù)退避避免斷網(wǎng)恢復(fù)時(shí)打爆服務(wù)端3.3 瀏覽器端的取舍原生 ping/pong 不可控走應(yīng)用層心跳瀏覽器里的WebSocket API沒有暴露ping/pong的控制能力你拿不到底層的pong事件。所以網(wǎng)頁端通常退而求其次采用應(yīng)用層心跳前端定時(shí)發(fā)一條業(yè)務(wù)心跳服務(wù)端更新lastSeen并用服務(wù)端的定時(shí)掃描兜底。這不算違反協(xié)議層心跳原則而是平臺限制下的務(wù)實(shí)選擇。應(yīng)用層心跳的收發(fā)兩端格式要對齊我常駐的字段是{ type: heartbeat, ts: 1717300000000 }前端每25秒發(fā)一次比服務(wù)端30秒的判定窗口略短服務(wù)端收到后只更新時(shí)間戳不往業(yè)務(wù)消息隊(duì)列里塞。要注意應(yīng)用層心跳消息不要把數(shù)據(jù)寫進(jìn)Redis之類的存儲里否則線上幾十萬連接每分鐘會產(chǎn)生幾百萬次寫入純屬浪費(fèi)。// 前端瀏覽器端心跳LAS 網(wǎng)頁端 const HEARTBEAT_APP_LEVEL 25_000; let heartbeatTimer null; function startHeartbeat(ws) { stopHeartbeat(); heartbeatTimer setInterval(() { if (ws.readyState WebSocket.OPEN) { ws.send(JSON.stringify({ type: heartbeat, ts: Date.now() })); } }, HEARTBEAT_APP_LEVEL); } function stopHeartbeat() { if (heartbeatTimer) clearInterval(heartbeatTimer); } // 頁面卸載時(shí)一定要清定時(shí)器否則頁面關(guān)了還在空發(fā) window.addEventListener(beforeunload, stopHeartbeat);前端還有一個容易被忽略的點(diǎn)onclose事件的延遲。網(wǎng)絡(luò)斷開時(shí)瀏覽器不一定立刻觸發(fā)onclose可能需要幾十秒甚至更久。所以前端不能只依賴onclose來啟動重連更穩(wěn)的做法是同時(shí)監(jiān)聽onerror和onclose并在每次發(fā)送消息失敗時(shí)也觸發(fā)一次重連檢查。重連時(shí)要把連接重新注冊一遍這一點(diǎn)后面第5章會專門講它是最常見的掉線恢復(fù)翻車點(diǎn)。4. 多端消息的路由從 A 端發(fā)起到 B/C 端到達(dá)連接和心跳都就緒后核心業(yè)務(wù)邏輯才上場一條消息從某個端進(jìn)來服務(wù)端決定往哪幾個端轉(zhuǎn)發(fā)。這個章節(jié)說的不是某個具體業(yè)務(wù)而是LAS多端互通里通用的消息分發(fā)骨架。協(xié)議定得好不好直接決定后面接多少個業(yè)務(wù)類型都不慌。4.1 消息信封與消息類型先定協(xié)議再寫代碼我習(xí)慣給所有WebSocket消息統(tǒng)一包一個信封而不是各業(yè)務(wù)發(fā)各的裸JSON。信封字段如下字段類型說明msgIdstring全局唯一用于去重與回執(zhí)typestring業(yè)務(wù)類型如 las.template.update / las.task.statusfromstring發(fā)送者 clientIdtostring目標(biāo)clientId / roomId / broadcastpayloadobject業(yè)務(wù)數(shù)據(jù)tsnumber客戶端時(shí)間戳這個信封的好處是路由層只認(rèn)msgId、type、to三個字段完全不用關(guān)心payload里的業(yè)務(wù)結(jié)構(gòu)。后面每接一個新業(yè)務(wù)只需要新增一個type路由邏輯一行不用改。LAS業(yè)務(wù)里我至少會分成三類實(shí)時(shí)同步類模板變更、狀態(tài)流轉(zhuǎn)、指令類強(qiáng)制刷新、踢下線、文件類二進(jìn)制分片。一個type字段就可以區(qū)分這些不要讓路由層靠識別payload里的字段名做判斷。4.2 路由與回執(zhí)目標(biāo)離線時(shí)消息怎么辦路由層要做的事是解析to然后到userMap或roomMap里查出目標(biāo)連接逐個發(fā)送。如果目標(biāo)端不在線LAS消息必須有個落地方案否則這條變更就丟了。離線消息的策略我推薦「Redis List暫存 登錄后主動拉取」而不是服務(wù)端無限期給每個離線用戶堆消息。// router.js —— 消息分發(fā)與離線暫存假設(shè) Redis 已通過 ioredis 初始化 async function dispatchMessage(raw) { const msg JSON.parse(raw); const { msgId, type, from, to } msg; const targets resolveTargets(to); let anyDelivered false; for (const connId of targets) { const ws connMap.get(connId); if (ws ws.readyState 1) { ws.send(JSON.stringify(msg)); anyDelivered true; } } if (!anyDelivered) { // 目標(biāo)連接全不在線按 clientId 維度暫存最近 50 條 const key las:offline:${to}; await redis.lpush(key, JSON.stringify(msg)); await redis.ltrim(key, 0, 49); // 只保留最新 50 條防止堆爆 await redis.expire(key, 7 * 24 * 3600); // 7 天有效期兜底 } return anyDelivered; }resolveTargets需要處理三種to值clientId就展開成userMap里的Set roomId就展開roomMapbroadcast就直接返回所有在線連接。注意anyDelivered只代表「發(fā)出去了」不代表對端業(yè)務(wù)處理成功。如果需要端到端確認(rèn)由對端回一條ack消息服務(wù)端再更新消息狀態(tài)。這個ack環(huán)節(jié)在LAS里很重要尤其是桌面端改模板后手機(jī)端必須確認(rèn)收到光靠「發(fā)出去了」是不夠的。還有一點(diǎn)ws.send在底層socket緩沖滿時(shí)可能拋出異常。大文件消息尤其常見需要在send外面包try/catchcatch到就用terminate處理這個連接別讓異常影響消息循環(huán)里的其他連接。4.3 去重與順序同一個用戶的多個端別互相打架一個用戶三個端同時(shí)在線的時(shí)候最容易出現(xiàn)兩類問題。第一類是消息重復(fù)桌面端發(fā)起模板更新服務(wù)端廣播給三個端手機(jī)端和網(wǎng)頁端各收到一次前端如果都做了彈窗提示用戶會看到兩條一樣的信息。第二類是順序錯亂桌面端先發(fā)了「開始同步」又發(fā)了「同步完成」但由于兩條消息走了不同的實(shí)例或線程服務(wù)端可能把后面那條先發(fā)出去。去重方案是在服務(wù)端維護(hù)一份msgId的最近緩存。每收一條消息就把msgId塞進(jìn)Redis的SET并設(shè)置過期時(shí)間比如10分鐘重復(fù)的msgId直接丟棄。注意這里去重的是「同一事件」而不是「同一事件的多次廣播」廣播給三個端是業(yè)務(wù)需要的不沖突。順序問題更頭疼單實(shí)例里可用一個簡單的自增seq保證同連接的消息有序多實(shí)例場景下需要讓同一個clientId的消息始終進(jìn)同一個消息隊(duì)列或分片才能嚴(yán)格保序。對LAS這種實(shí)時(shí)協(xié)作場景我通常只在同一連接維度保序跨端全局強(qiáng)一致投入產(chǎn)出比不高。// dedup.js —— 最近 10 分鐘的 msgId 去重 async function isDuplicate(msgId) { const key las:msgdedup:${msgId}; // setnx 成功說明第一次見失敗說明重復(fù) const ok await redis.set(key, 1, EX, 600, NX); return !ok; }去重放在路由之前。收到消息先查重復(fù)再走dispatch。一個看似小但實(shí)際很關(guān)鍵的細(xì)節(jié)msgId的生成不能在服務(wù)端統(tǒng)一生成而要由發(fā)起端生成。原因很簡單用戶可能在桌面端先發(fā)出了消息但因?yàn)榫W(wǎng)絡(luò)沒到達(dá)服務(wù)端隨后手機(jī)端又發(fā)起一次同樣操作如果msgId是服務(wù)端生成的這兩條消息永遠(yuǎn)無法被識別為同一條。5. 多端互通排查5 個常見坑與現(xiàn)場處理辦法WebSocket踩坑的路徑高度重復(fù)以下五條每一個我都實(shí)打?qū)嵱龅竭^現(xiàn)象、原因和解決辦法按順序?qū)懩憧梢詫φ罩掷锏娜罩九挪椤?.1 Nginx 靜默掐斷空閑連接現(xiàn)象客戶端連接建立后隔一段時(shí)間恰好是60秒左右就收到onclose服務(wù)端日志里沒有任何close記錄。原因Nginx作為反向代理時(shí)默認(rèn)proxy_read_timeout是60秒在這段時(shí)間內(nèi)如果后端沒有數(shù)據(jù)返回Nginx會主動斷開連接。WebSocket的連接恰恰大部分時(shí)間沒有數(shù)據(jù)流動于是被當(dāng)成空閑超時(shí)掐斷。解決在Nginx的location里顯式關(guān)閉代理超時(shí)。location /ws/ { proxy_pass http://las_ws_backend; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection upgrade; proxy_read_timeout 3600s; proxy_send_timeout 3600s; }注意proxy_set_header Connection那行必須寫成upgrade否則WebSocket握手在Nginx這一層就失敗。這個坑的癥狀是連得上但馬上斷開和心跳無關(guān)。5.2 心跳間隔不一致導(dǎo)致誤殺現(xiàn)象客戶端明明在線卻頻繁被服務(wù)端斷線重連。原因服務(wù)端心跳判定閾值設(shè)的30秒客戶端的應(yīng)用層心跳發(fā)的倒是挺勤但客戶端所在的網(wǎng)絡(luò)環(huán)境有丟包pong幀偶爾沒回來連續(xù)兩個周期沒收到pong就被service端誤殺。解決把服務(wù)端的容忍閾值從2個周期放寬到3個周期同時(shí)讓客戶端的應(yīng)用層心跳間隔比服務(wù)端探活間隔短至少5秒留出余量。誤殺重連不是大事但每次誤殺都會帶來一次重連風(fēng)暴連接數(shù)多了會產(chǎn)生雪崩效應(yīng)這個參數(shù)值得多調(diào)幾輪。5.3 斷線重連后消息繼續(xù)發(fā)給舊連接現(xiàn)象用戶手機(jī)切了Wi-Fi再切回來連接斷了又重連成功但之后服務(wù)端發(fā)的消息他總是收不到。原因前端重連后只建立了新的TCP連接沒有重新發(fā)起注冊握手服務(wù)端userMap里用戶的connectionId還是舊的消息全發(fā)給了已經(jīng)死掉的舊連接。解決把「連接建立」和「連接注冊」做成兩個明確的階段前端必須在onopen之后等待注冊響應(yīng)服務(wù)端注冊成功再收業(yè)務(wù)消息。最常見做法是重連后第一條消息一定是register。// 客戶端重連后必須重新 register不能只 new WebSocket() function connectWithRegister() { const ws new WebSocket(wss://las.example.com/ws?clientIdU10086); ws.onopen () { ws.send(JSON.stringify({ type: register, clientId: U10086 })); }; }服務(wù)端把register消息放進(jìn)用戶白名單沒注冊的連接拒絕轉(zhuǎn)發(fā)業(yè)務(wù)消息。這個約束能直接避免重連后消息丟失的黑匣子問題。5.4 多端在線時(shí)的消息重復(fù)與回顯問題現(xiàn)象A端發(fā)一條消息B端、C端都收到了但A端自己也收到了一份服務(wù)端回顯前端沒有過濾界面上出現(xiàn)兩條自己發(fā)的消息。原因廣播邏輯沒有排除發(fā)送者連接或者前端沒有對本地發(fā)送的消息做ack去重。解決服務(wù)端廣播時(shí)排除from的connId前端也最好把「自己發(fā)出的消息」直接渲染成pending狀態(tài)收到ack再變成已送達(dá)而不是等廣播回來再渲染。LAS里桌面端和網(wǎng)頁端經(jīng)常共用一個賬號回顯去重尤其要注意。5.5 Sending on closed socket 異?,F(xiàn)象服務(wù)端日志頻繁出現(xiàn)Error: Sending on closed socket偶發(fā)進(jìn)程崩潰。原因連接在ws.send之前剛被關(guān)閉但connMap里還殘留引用代碼直接往已關(guān)閉的連接上寫數(shù)據(jù)。解決發(fā)消息前檢查readyState 1只是第一道保險(xiǎn)還要在send外面包try/catchcatch住就直接清理連接索引。不要小看這個錯誤流量高峰時(shí)它會拖垮整個消息循環(huán)屬于高發(fā)事故源。// safeSend.ts —— 帶兜底的發(fā)送封裝 function safeSend(ws, raw) { try { if (ws ws.readyState 1) ws.send(raw); } catch (e) { // 連接已死清索引并終止 connMap.delete(ws.connId); ws.terminate(); } }6. 進(jìn)階多實(shí)例擴(kuò)展與端到端驗(yàn)證單機(jī)跑通只是開始LAS多端互通要上生產(chǎn)單實(shí)例撐不住所有在線連接橫向擴(kuò)展是繞不開的問題。一個用戶連在實(shí)例A另一個用戶連在實(shí)例B兩個實(shí)例之間的連接互相不知道對方消息就斷在中間。常見做法是引入Redis Pub/Sub作為實(shí)例間消息總線本地路由直接發(fā)本機(jī)連接跨實(shí)例消息通過Redis發(fā)布所有實(shí)例都訂閱同一個頻道收到后檢查目標(biāo)連接是否在自己這里。// cluster.js —— 多實(shí)例橋接本地直接路由跨實(shí)例走 Redis 廣播 const sub new Redis(); // 訂閱連接 const pub new Redis(); // 發(fā)布連接 sub.subscribe(las:ws:cluster); sub.on(message, (_channel, raw) { const envelope JSON.parse(raw); // 只有目標(biāo)連接在本實(shí)例才處理避免 A 實(shí)例收到又轉(zhuǎn)發(fā)回 B 實(shí)例 dispatchMessage(envelope); }); function sendCrossInstance(targetConnId, msg) { pub.publish(las:ws:cluster, JSON.stringify({ target: targetConnId, msg })); }端到端驗(yàn)證我習(xí)慣用Node腳本模擬多端同時(shí)在線而不是靠手工開幾個瀏覽器窗口戳來戳去。用ws庫起一個測試客戶端同時(shí)模擬桌面端、網(wǎng)頁端、手機(jī)端三個身份連到同一個clientId下然后讓一端發(fā)消息斷言另外兩端都能收到再手動調(diào)低心跳閾值驗(yàn)證斷線重連。// test.js —— 模擬 100 個并發(fā)端做聯(lián)調(diào) const WebSocket require(ws); function createTestClient(clientId, port 8080) { const ws new WebSocket(ws://127.0.0.1:${port}/ws?clientId${clientId}); ws.on(message, (data) { const msg JSON.parse(data.toString()); if (msg.type las.template.update) { console.log([${clientId}] 收到模板更新:, msg.payload.version); } }); return ws; } // 同時(shí)模擬 100 個用戶在線 const clients Array.from({ length: 100 }, (_, i) createTestClient(U${10000 i}) ); // 等 2 秒連接全部建立再從 U10000 廣播一條模板更新 setTimeout(() { clients[0].send(JSON.stringify({ type: las.template.update, to: broadcast, payload: { version: v2.3.1 } })); }, 2000);跑這個腳本時(shí)重點(diǎn)觀察兩個指標(biāo)一是100個連接同時(shí)注冊時(shí)服務(wù)端有沒有內(nèi)存突增或報(bào)錯二是廣播后是否每個端都收到了且只收到一次——重復(fù)也說明路由有問題。我自己的教訓(xùn)是多端互通上線前一定要專門做一次「殺掉服務(wù)端」的演練看客戶端重連能不能在30秒內(nèi)全部恢復(fù)賬號信息會不會因?yàn)橹剡B而丟。這個演練花錢最少、救急最多。LAS多端互通的實(shí)現(xiàn)鏈條就是這樣連接注冊、心跳判定、消息路由、多實(shí)例橋接每層都守住邊界端和端之間才能安靜地實(shí)時(shí)同步。希望這些踩出來的經(jīng)驗(yàn)幫到你。本文還有配套的精品資源點(diǎn)擊獲取
返回列表
PREV
查看更多資訊
NEXT
返回資訊列表
琪琪色五月天| 色情五月丁香婷婷网| 久久精品系列| 99rewww| 亚洲宗合激情| 99爱在线精品视频免费观看| 丁香六月无码播放| 国产伊人五月天| 国产SUV精品一区二区883| 天天爽夜夜爽天天爽夜夜爽| 国产成人亚洲综合A∨婷婷| 视频在线免费观看欧洲乱码| 丰满人妻妇伦又伦精品国产| 少妇高潮一区二区三区99欧美| www,色综合| 120分钟婬片免费看| 五月丁香综合啪啪啪啪啪| 97伦乱| 日韩aaaaa| 婷婷色五月噜噜| 欧美在线视频99| 桔色成人在线| 亚州性爱99| 成人丁香五月| 黄色成人网站在线播放| 91久久九| www.99热精品99.com| 亚洲超碰在线| 天天干天天日天天操| 婷婷五月丁香久久| 婷婷色五月天综合网| 另类A片| 操操综合网婷婷| www.婷婷.com| 99热自拍| 久久九九网| 色婷婷丁香五月天| 99视频热| 天天操天天草天天草天天| 色五月xxx| 五月伊人婷婷999| 人妻熟人中文字幕一区二区| 欧美操人| 疯狂做受XXXX高潮A片| 9 1超碰九色| 丁香五月婷久久| 日 日干 日日做| 婷婷五月AV| 成人一区在线观看| 久久99精品久久久久子伦| 9|人妻人人操| 国产伊人大香蕉| 无遮挡国产高潮视频免费观看| 五月丁香激情综合网| 99在线精品视频| 日韩99精品| 五月四色婷婷| 九九热在线观看视频| 五月婷婷综合潮喷| 六月激情婷婷| 日本久久人人| 色色com| 日夜操B| 久久婷婷内射| 五月天婷婷基地| 激情五月综合| 在线看片h站| 五月婷婷天堂| 国产 码在线成人网站| 婷婷五月天开心网| 婷婷色婷婷| 91视频精品99| 强壮公让我夜夜高潮A片视频| 思思热视频在线观看| www.91操| 中文字幕无码AV| 婷婷五月久久| 久超超碰| 99热欧| 丁香婷婷综合五月天| 激情五月婷婷网在线观看| 伊人久久激情图区五月| 色,激情五月天| www.激情.com.| 精品色情一区二区三区四区| 99精品综合视频| 色综合色色| 玖玖五月丁香| 亚洲色欲AAAAAA| 婷婷精品性性性性性性性| 狠狠五月综合在线 | 欧美另类五月激情| 激情影院丁香五月| 五月天开心网| 夜色综合网| 五月天丁香综合久久国产| 亚洲AV网站在线观看| 67194成I人在线观看线路1| 亚洲 综合中文| 婷婷五月免费观看| 九九精品综合| 拍色综合| 五月丁香在线国产 | 四月婷婷丁香五月| 亚洲激情婷婷| 丁香色影院| 久热综合| 97色色色| 日韩少妇内射免费播放| 色久女| 天天日天天摸天天| 色色五月天婷婷| 丁香五月激情综合| AV在线免费播放| 五月婷婷久久激情| 五月丁香婷婷成人网| 亚洲精级| 五月丁香色五月| 久久99激情丁香婷婷小说网| 666555。COm毛片| 久操97| 激情五月婷婷在线区| 天天日夜夜拍| 停婷丁五月在线| 天天色丁香| 亚洲性爱AV在线| 日本激情91| 色综色五月天婷婷| 国产69久久久欧美黑人A片| 亚洲欧洲小视频9| 久久图色4| 亚洲 在线 性爱| 超碰操网| 久久久久久久久99精品| 激情五月综合婷婷| 国产精品岛国片在线观看免费| 久热超碰| 六月丁香激情网| 中文AV网站| 99r久久这里只有精品| 狠狠狠狠狠狠| 婷婷精品综合| 日韩在线观看亚洲| 婷婷久久五月天丁香| 综合图区激情| 色约约视频一区二区三区四区五区 | 色婷婷99| 丁香五月成人社区| 色亚洲无码| 婷婷九月在线| 亚洲无码免费看| 热久久66| 无码字幕中文| 深爱激情六月天| 91综合视频丁香| 综合久久丁香婷婷,五月婷婷六月丁香,开心激情综合网,六月丁香在线观看,婷婷丁 | 91在线观看www| 天天综合五月| 被强行糟蹋的女人A片| 婷婷综合激情| 色五月网址| 超碰碰碰碰| 色色色在线观看| 成人免费120分钟啪啪| 黄色aaaaa| 久久综合五月天| 狠狠爱婷婷爱| 99精品综合视频| 120分钟婬片免费看| 丁香激情久久| 五月天大香蕉| 激情综合网激情五月天| www.五月天婷婷姐姐| 国产毛多水多女人A片| 五月婷婷开心亚洲无| 婷香五月激情视频| 久久机只有这里精品| 疯狂做受XXXX高潮A片| 5月婷婷综合| 亚洲激情AV| 五月丁香亚洲五月| 久久码久久无清| 婷婷综合在线| 人人干人人干骚美女| 久久婷婷五月综合啪| 亚洲天堂啪啪| 无码免费人妻A片AAA毛片西瓜| 色情五月天se| 色色婷婷丁香五月天| 亚洲熟女色| 丁香蜜臀黄色婷婷五月天| 成人在线视频网| 狠狠色丁婷婷日日,伊人激情综合网 | 婷婷成人视频| 日本一级一片免费视频| 人妻体体内射精一区二区| 久热这里只有精品视频6| 久久探花91swag| 美女天天爽| 999婷婷综合| 久久9视频| 五月丁香AV在线| 五月天色色色色色| 麻豆AV一区二区三区| 久久深爱激情网| 2020日日干| 欧美婷婷| 91五月天| 欧美性色视频| 天天综合亚洲综合| 激情网站五月| 丁香九月激情久久| 婷婷色情 | 五月丁香在线婷婷蜜桃| 国产67194| www.夜夜| 亲子乱AV一区二区三区下载| 欧美日本一区二区三区| 成人色五月天婷婷| 97五月综合网| 色五月激情网| 五月丁香琪琪| 99精品视频网| 视色综合| 日本在线视频手机播放五月婷| 亚洲国产成人AV在线| 香蕉久久国产AV一区二区| 中文字幕 久久9999| 婷婷五月综合色中文字幕| 婷色五月天| 国产日韩欧美| 五月丁香六月婷婷亚洲| 久久色五月天| WWW久久久| 91九色白丝| 狠狠色狠狠| wwwC0maV五月花| 97人人草| 九月婷婷综合| 一区视频网站| 婷婷激情五月天小说| 开心五月天激情网| 日本色婷婷| 性欧美日本| 伊人久久丁香婷婷六月五月综合| 欧美色播综合在线观看| 六月婷婷狠狠| 包操45分钟网站| 国产熟女大叫受不了| 综久久久| 亚洲第二AV| 最近中文字幕2019视频1| 日韩成人AV在线播放| 婷婷五月天第三页| 婷婷五月丁香在线视频| www.色五月.com| 色久五月| av性爱在线| 五月激情六月| 丁香久色| 精品免费99| 婷婷狠狠五月综合| 日本熟女一区二区| 婷婷五月天Av| 狠狠色婷婷丁香六月| 99热这里只有99| VA色婷婷| 熟女五月天久久综合| 99热99思午夜精品| 五月天激情婷婷小说| 伊人五月人妻精品| 人妻精品久久久久久| 管管補管管紱| 狠狠插日日干撸| 婷婷精品性性性性性性性| 五月丁香六月欧美| 五月丁香婷婷综合| 欧美日韩成人在线| 国产乱子轮XXX农村| 国产伦亲子伦亲子视频观看| 国产69久久久欧美黑人A片 | 69人人操人人爽| 日本婷婷色| 丝袜熟女一区二区三区| www999日韩精品| 色婷精品91| 国产91视频| 色色五月天婷婷| 涩综合在线| www.色五月.com| 精品思思久久| 九九色色| 激情二色月| 婷婷丁香激情| 日本一级一片免费视频| 婷婷 伊人 久久| 色婷婷中文在线| 五月天伊人| 九九操屄| 九九色逼| 日韩在线五月天婷婷| 99热这里只有精品3| 97色女人在线| 国产亚洲精品久久久久久久久动漫 | 99热欧| 六月丁香激情婷婷| 中文字幕av久久爽一区| 久久99久久99久久99| 色色网91| 天天噪夜夜爽| 97色婷| 风流少妇A片一区二区蜜桃| 91VIP在线观看| 中文字幕AV在线播放| 99er6| 久久99激情丁香婷婷小说网| 性爱久久| 日韩精品超碰在线观看| 日韩六六久久电影| 九九黄色网| 久久六月婷婷| 99热九九这里只有精品10| 夜夜噜夜夜奇| 99热都是精品| 久久加勒比| 成人婷婷深爱综合网| 久久婷婷视频| 五月婷婷亚洲天堂97色婷婷| 久久久妻人人人| 婷婷丁香色情五月天| 99热这里精品| 97极品在线| 色婷丨日丨天丨综合久久| 五月天开心网| 五月丁香六月婷婷综合| 国产熟女日日骚五月丁香爱| 婷婷六月色| 4399高清无码视频| 欧美成人网99网| 99九九视频| 超碰在线观看成人视| 青草久久五月婷伊人| 大香蕉欧美在线| 亚洲欧洲中文日韩久久AV乱码| 丁香五月婷婷激情尤物| 欧洲亚洲精品| 99热www| 思思99re这里只有| 狠狠干无码| 国产无人区大片| 丁香五月网在线观看| 婷婷五月丁香五月| 婷婷久久色| 五月婷婷视频ab| 久久综合婷婷| 98毛片| 中文AV网| 国产操肏网站| 天天天天操| 1024在线视频| 九九视频这里只有精品| 激情性爱网站| 先锋资源91| 亚洲妇女熟BBW| 26UUU| 99热这里只有精品22| 五月天操逼网| 26uuu欧美| 超热久碰.com| 久久92| 免费啪啪亚州视频| 无码任你操| 色综合九九| 六月丁香啪啪| 五月天伊人av| 亚洲美女裸体被操在线观看| 亚洲色亚洲精品| 亚洲性爱AV在线| 丁香综合伊人AV| 亚洲电影在线观看| 五月天另类小说| 精品操逼一区二区| 久久98热re| 久久大香蕉视频| 婷婷色五月开心五月| 日本婷久久| 五月丁香婷庭在线| 996er热| 婷婷激情五月| 丁香五月六月婷婷自拍| 色情成人五月天| 热99这就是精品视频| 91精品又长又大又粗又爽又猛| 久久总和99| 久久久www| 另类激情综合| 华人在线免费| 97在线刺激| 五月婷婷激情| 五月丁香色婷婷伊人| 成人免费120分钟啪啪| 亚洲五月综合色播| 97人妻碰碰碰久久香蕉| 国产乱妇乱子在线播视频播放网站 | 激情婷婷。| 久久综合影院| 成人婷婷五月天| 四色五月婷婷| 日韩婷婷| 婷婷五月天人妻| 伊人久久大香天蕉亚洲特级| 激情网五月天| 人人草人人爱| 五月婷婷中文网| 操婷婷久久| 六月丁香婷| 欧美97p| 婷婷五月综合网| 日本久久天堂| 欧美色六月婷婷| 欧美色色色色色色| 色噜噜狠狠色综合日日| 天天日天天干天天操| 五月婷婷综合激情网| 大战熟女丰满人妻AV| 国产精品久久久海的味道| 久久伊人9| 青柠影视免费高清电视剧| 五月婷婷丁香社区| WWW五月天| 五月天社区婷婷丁香社区| AA丁香综合激情| jizzdr| 婷婷激情五月天综合| 日韩久久成人| www99热| 99热在线精品观看| 婷婷五月综合丁香久久| 国产午夜精品AV一区二区麻豆| 99视频精品在线| 色色色色色级无码| 久操人妻| 色婷婷A| 五月婷婷丁香日韩在线| 无码99| 国产综合色婷婷精品久久| 婷婷综合激情五月综合| 99热国内| 亚洲综合视频天天精品| 狠狠干婷婷| 久草丁香婷婷五月天婷| 天天久久九九| 丁香五月电影| 99热成人| 五月激情综合网| 日本色久| 99riAv1国产在线观看| 久久婷婷五月综合激情国产| 思思热久在线观看视频| 婷婷五月综合激情| 久久久人妻人伦| 一区二区免费看| 五月天激情日色在线| 9久热精品在线视频| 久超超碰| 天天狠狠六月婷丁香影院| 激情婷婷五月天在线观看| 日韩五月婷婷| 99re这里只有精品国产99| 色婷婷最新域名| 婷婷五月丁香亚洲| 婷婷情色五月| 9999综合99综合人| 五月亭亭欧美女人| 丁香五月色五月| 激情九九六月激情免费视频| 九九精品热播| 大香蕉久久久久| 五月婷婷丁香综合| 伊人网碰碰| 97操碰碰无码视频| 九九日本视频| 俺去也在线官网| 色热久资源| 久久丁香五月综合六月激情红杏视频| 五月婷婷丁香啪啪| 色情五月天小说| 国产五月丁香在线| 综合丁香婷婷五月天| 91碰在线| 思思热99er在线视频| 色五月婷婷、老熟女| 丁香五月亚洲婷婷| 丁香五月综合在线| 久久人妻伊人| 狠狠的日| 99无码| AA片在线观看视频在线播放| av一区二区电影免费在线观看| 人妻六月天| 亚洲婷婷综合视频| 久久久久久久久久8888| 天天综合天天玩夜夜玩天天玩夜夜玩 | 天天情色综合网| 婷婷五月天开心激情网| 99热免费精品| 欧美成人AAA片一区国产精品| 日本激情综合| 亚洲在线综合| 久久精彩视频99| 丁香五月天资源网| 久草五月婷婷| 大香伊人久色| 99热99草97| 亚洲成人AV在线| 热99玖玖99玖玖99九九| 激情综合网五月丁香| 蜜臀A∨在线水帘洞| 伊人9999| 天天日夜夜拍| 五月天伊人| 91美女艹逼网站| 婷婷五月香蕉| 精品,99| 日韩黄黄| 在线sebiav精品视频| 激情综合五月天| 先锋资源 996| 亚州操人在线视频| 嫩草视频在线观看| www.玖玖婷婷在线| 综合狠狠干| 九九热婷婷| 深爱激情综合| 久久综合婷婷| 婷婷丁香六月天激情四射网| 99久久免费性爱视频`| www 五月天 com| 欧美va在线| 久久综合综合综合| 婷婷激情鹿城五月天| 男人天堂99| 性爱七区| 丁香五月开心婷婷| 五月婷婷综合激情小说| 五月激情六月| 另类图片五月天| 久久综合久色欧美综合狠狠| 久久激情视频| 色哟哟www| 伊大人久久| 99热这里只有99| 少妇人妻人伦A片| 日韩成人网址| 综合一区二区三区| 99re思思热久久| 一级韩国产精品毛| 九色视频91| 美国色五月天婷婷资源站| 伊人91| 久久精品综合色| 色噜噜狠狠狠综合曰曰曰| 丁香六月综合激情| 五月天播播综合| 久久丁香五月| 午夜丁香丁香婷婷| 国产午夜一区二区三区| 青青草99热久久精品国| www.五月丁香| 丁香九月综合在线| 国产精品色婷婷AV综合色色| 色很久综合| 天天摸色吧天天摸色吧| 91精品久| 五月婷婷官网色| 九月婷婷综合网| 天天色天天操天天射| 91在线看片| 色噜噜婷婷| 亚洲va久久久噜噜噜久久天堂| 丁香五月狠狠综合欧美| 国产亚洲成人综合| 天天摸天天透天天舔| 久久蜜臀婷婷| 91丨九色丨熟女| 人妻熟妇国产精品| 97色色色| 婷婷五月天熟妇| 级人人91| 五月丁香啪综合| 99色热视频| 色噜噜狠狠色综合日日| ri电影在线| 色婷婷五月天av在线| 天天综合网亚洲网站| 欧美日韩精品一区二区三区钱| 丁香五月激情婷婷婷婷在线观看| 久操激情| 亚洲爆乳无码精品AAA片蜜桃| 成人色情五月天婷婷丁香| 欧美成人AAA片一区国产精品| 精品无码99| 国产亚洲色婷婷久久99精品91 www.riverspirits.org www.hnnun.com www.changh | 中文字幕av在线| 久9热视频在线观看| 人妻av在线| 啪啪五月天啪啪| 色色色色色色色五月| www.婷婷五月天.com| 91操片| 国产午夜精品AV一区二区麻豆| 五月婷婷久草在线视频综合| 人人操操| 天天综合精品| 日本一级特黄大片AAAAA级| 久久这里只有精彩| 超碰在线免费观看3 9| 538在线精品| 天天色综合色色色色色。| 91狠狠色丁香婷婷综合久久狠丁香综合久久精品| 区区欧美你爱| 国产成人av在线| 婷婷五月综合中文字幕| 99热这里是精品| 欧洲综合视频在线观看。欧洲,亚洲综合食品在线观看。 | 天天干天天干天天| 五月综合色播播丁香婷婷| 九九综合久久| 一本婷婷丁香久久 | 最新日本A片| 色色五月激情| 久热99| 五月天婷婷视频小说| 99在线观看视频免费| 视频1区2区| 五月丁香影院| 99超级碰碰| 夜夜爽日日躁| 五月丁香啪啪啪免费看| 五月婷婷综合社区| 婷婷五月久久| 天天色天天| 熟女网站久久| 婷婷开心激情五月激情网| 性爱先锋AV| 日本久久爽| 欧美天堂婷婷日韩| 天天爽天天| 91avse| 来吧亚洲综合网| 五月色婷婷AV| 丁香六月 婷婷六月| 色色色在线观看| 久久资源综合| aaaa久久| 久久久天堂国产精品女人| 五月丁香六月| 色噜噜狠狠色综合日日| 久久92| 丁香五月天AV| 亚洲天天| 婷婷色情六月| 色欲资源网| 噜噜干日本| 婷婷五月天综合久久| 日韩无码亚欧无码| 蒲京久久无码视频| OYIWbGcPu8H| 欧美槡BBBB槡BBB少妇| 狠狠操狠狠插| 五月天伊人网| 大香蕉综合网| 夜夜谢天天干| 丁香五月婷婷基地| 超碰91在线| 色99视频| 亚洲乱码日产精品BD| 狠狠干夜夜干| 五月天婷婷久久| 思思99热| 99热这里| 丁香六月婷婷色XXXX| 日本人人超碰| 天天干 夜夜爽| 九九在线精点品| 人人摸人人搞| 26uuu国产| 极品人妻VIDEOSSS人妻| 五月天色色无码| A片试看120分钟做受图片| 免费无码毛片一区二区A片| 免费在线观看AV网站| 亚洲精品又粗又大又爽A片| 激情五月天网站| 国产精品电影| 97色干在线观看| 色婷婷激情五月天丁香| 操操熟女| 久久婷婷精品| 亚洲综合视频一下| 欧美VA在线| 色偷偷色婷婷| 久热免费视频| 天天操天天插天天射| 2022人人操人人看| 91久久婷婷| 九六五月天婷婷| 蜜桃五月天| 日韩av在线免费观看| 九九精品亚洲| 中文字幕丰满孑伦无码专区| 91 久热| 五月天婷婷伊人| 丁香五月自拍| 婷婷五月天激情丁香| 另类小说五月天| 激情婷婷| 婷婷伊人五月丁香天堂网| 精品女人九九九| 五月婷六月综合在线观看| 色五月丁香伊人| 99re视频在线播放| 第四色在线观看| 久久五月婷婷丁香| 九九热这里都是精品6| 色情五月停停丁香| 婷婷五月在线观看| 丁香五月五月婷婷欧美大香蕉| 99热一本| 亚洲视频丁香网va| 色久九| 九九色婷| 人人爽天天莫| 五月天综合网| 苗黎美女四级成人版一级二级毛片| 热久69| hd五月婷婷在线| 97人人操| 99情色五月天| 99久久婷婷国产综合精品草原| 丁香五月天激情五月天激情五月天激情网| 五月天婷综合| 丁香五月婷婷丫| 激情爱爱网站| 波多野结衣成人作品在线| 久久综合激情| 五月叮香啪| 婷婷五月丁香青青草在线| 成人AV在线网站| 丁香五月色欲| 精品热青草| 开心五月天私房婷婷| 久9视频免费播放| 在线99热| 97色在线| 99热99精品| 五月色亭丁香| 九九视频这里只有精彩| 午夜69成人做爰视频| 久操福利| 综合视频久久| 成人短视频在线免费观看| 俺去也在线官网| 无码人妻精品一区二区蜜桃色欲| 日本三级韩三级99久久| 中文字幕 中文字幕明步| 丁香婷婷五月天成人| 婷婷五月天国产手机在线视频观看| 日本美女上人| 亚洲成人综合网在线免费观看| 六月色色| 影音先锋一区二区三区| 91日视频| 天天日天天舔| 久xxxx| 激情五月,婷婷五月,丁香五月| 丁香五月婷婷av影院| 天天色五月| 激情五月婷婷| 久久精品爱爱| 国产精品国产成人国产三级| 色色日韩| 欧洲色| 五月色 亚洲| 五月丁香综合网| 狠狠色婷婷777| 怡红院视频| 色情五月丁香| 五月天婷婷激情小说电影| 五月色综合网欧美网| 亚洲综合色色色| 免费AAAAA网| 精品久久99| 婷婷丁香五月天综合网| 国产古装妇女野外A片| 五月激情另类| 色五月av| 人妻肉射免费观看| 五月丁香亭亭A片| 激情综合五月开心狠狠| a在线免费v| 色欲天天综合| 婷婷丁香五月天综合网| 爽tv | 天天做天天爱综合| 久久综合伊人77777蜜臀| 亚洲国产成人在线| 成人va在线观看视频| 《亚洲操B久久免费在线观看,亚洲操B久久在线播放》在线播放 - 高清资源 - 97 | 成人在线日韩欧美| 久综合| 五月大香蕉| 偷拍丁香九月激情| 激情五月天小说| 婷婷五月综合色拍| 亚洲精品久久久久久久久久吃药| 久久机只有这里精品| 国产操逼视频网站| 五月天婷婷在线AN| 99re思思热这里| 九色激情| 九九精品免费| 综合五月激情网| 天天综合网91| 色五月激情五月| 六月综合婷婷开心伊人| wWw色五月| 婷婷干| 超碰免费大香蕉| 日操五月婷| 亚洲久艹| 激情综合网五月婷婷| 国产日韩欧美| 激情五月天婷婷激情| 狠狠色色色| 色播综合| 丁香五月中文字幕久色| 91九色国产在线| 99久久婷婷国产综合精品| www.天天干| 久久婷婷色综合| 狠狠爱深色婷婷综合| 国产精品国产| 一本综合丁香日日狠狠色| 久久伦乱| 激情98色婷婷五| 色色色免费视频| 人人爱人人摸人人澡| 天天日天天做天天舔| 五月婷婷色白丝| 亚州美女| 久热 91| 丁香五月激情啪啪| 亚洲久久视频| 丁香六月啪啪| 婷婷五月天丁香激情| 噼里啪啦完整版中文在线观看 | 在线婷婷| 一级黄色尤物综合视频手机在线观看| 婷婷五月丁香综合亚洲 | 综合五月婷婷| 五月婷婷五月色| 热99热9| 六月丁婷婷| 超碰97干| 九九色大香蕉| 高清av在线国产| 激情综合网激情五月俺也去| 成功精品影院| 久99久热| 亚洲婷婷久久综合| 国产玖玖资源| 五月开心激情网| 激情网五夜婷婷| 色性综合| 91精品久久久久久久| 人妻在线网站| 国产a视频| 曰韩五月丁香色婷婷无码| 精品一二三区久久AAA片| 亚州色婷婷| 亚洲综合另类| 六月天婷婷| 婷婷五月天在线综合| 天天爽天天爽夜夜爽| RenRenSe在线视频网站| 婷婷开心深爱五月天| 综合九九久久| 影音先锋男人资源站一区二区| 色综久久久| 亚洲人操亚洲人| 成人AV在线中文版| 嫩草AV久久伊人妇女超级A| 另类视频在线| 色婷婷六月| 婷婷色在线| 六月婷婷色综合| 97超碰人人操| 直接看的AV| 丁香午夜天| 7月婷婷六月丁香| 99热99网| 深情六月婷婷综合久久| 777丁香六月青青草婷婷综合久月| www.av视频xx999.com| 丁香五月网站| 五月婷婷久久内射| 色噜噜狠狠色综合日日免费| 538在线| 色五月天天| 亚洲AAAA网| 看久久性爱99视频| www.色婷婷| 97久久人人| 六月激情网| 艳妇野外情欲放荡HD| 色婷婷精| 一本色道久久88加勒比—| 97精品在线| 人人爱干人人爱草| 婷婷久久六月天| 激情五月婷婷六月丁香| 天天弄天天操| 久久久婷婷婷| 国产精品久久久久9999小说| 婷婷丁香无码专区| 丁香五月激情网| 99久视频| 丁香五月婷婷精品视频| 丁香综合婷婷五月天| 五月丁香av中文| 国产毛片精品一区二区色欲黄A片| 丁香婷婷九月在线| 婷婷国产五月天17c| 五月婷婷激情网| 狠狠婷婷爱| 思思热在线观看| 五月丁香成人网| 字幕网AV中文字幕| 一级性感黄色内射视频| 秋霞午夜理论| 五月丁香六月色| 夜夜撸天天操| 草草色情综合网| 草草操操| 久久这里只有精品16| 97色热| 无码AV免费精品一区二区三区| 五月天天综合网色婷婷| 亚洲小视频免费播放| 99久久er| 五月丁香| 丁香深五月婷婷| 丁香五月手机视频| 欧美va国产va| 播五月,色五月,开心五月播放器| 丁香五月婷婷基地| 久久人视频| 亚洲激情五月婷婷日日| 五月天伊人网| 激情av| 婷婷五月丁香超碰| 色五月开心五月激情五月| 五月婷婷|欧美| 三人荫蒂添的好舒服A片| 蜜乳人妻一区二区三区| 96性爱视频| 九九热99视频| 丁香激情五月少妇| 成人婷婷深爱综合网| 婷婷久久网| 四季日韩AV无码综合| 色婷婷91激情小说| 9久久久久久久久久久| 影音 五月 婷婷 久久| 色婷婷五月天亚洲| 香蕉人在线香蕉人在线 | 一本道在线电影| 五月天啪啪| 2025天天日爽| 日韩小视频在线99| 色婷婷丁香五月天在线视频| 欧美性爱五月天| 99资源人人| 色狠狠伊人久久五月丁香| 五月婷激情| 伊人碰碰婷婷| 妻久久人久久| 综合久久五| 超碰人人艹| 五月婷婷在线视频观看| 婷婷综合中文| 26uuuavcom| 五月丁香影院| 婷婷五月激情四月综合 | 国产白丝在线一区| 秋霞av不能| 99精品视频网站| 中文字幕视频色婷婷| 五月婷婷综合激情| www.婷婷.com| 婷婷激情中文综合| 欧美影院婷婷| 久re在线| 大地资源色婷婷视频在线| 九九热视频在线观看| 激情网五夜婷婷| 九九99久久| 快乐婷婷五月天| 五月天综合婷婷| 开心五月婷婷激情| 美女网黄| 色综合久久88色综合天天| 99久久玖玖| 中文字幕操比影片| 真实亲子乱子伦高清在线观看| 99色在线观看视频者| 欧美激情综合色综合色| 五月天天丁香婷婷| 婷婷五月天在线观看免费| 五月丁香综合色婷婷| 激情婷婷五六月天| 五月婷婷六月丁香| 婷婷五月天成人动漫 | 成人色情五月天婷婷丁香| 丰满少妇猛烈A片免费看观看| 欧美日本综合网| 久久精品国产AV一区二区三区 | 婷婷五六日| 亚洲人成播放网站| 九九99精品视频在线观看| 3p久久| 欧洲亚洲免费视频9| 操人精品| 色五月婷婷五月| 久久久er热| av网站免费在线| 色色色色色色色色网站| 亚洲一级色电影| 久草热在线视频| 五月婷婷综合色啪首页| 亚洲六月综合激情久久下卡| 人。妻久久| 99热这里只有精品1025| 日日干日日| 嫩草AV久久伊人妇女超级a| 在线播放 精品| 婷婷色啪| 爱性综合网| 九九色婷婷五月天| 26uuu| 九九综合久久| 国产黄大片在线观看画质优化| 色婷五月天激情| 五月天丁香成人| 免费视频WWW在线观看网站| 婷婷五月天成人影片| 久9视频免费播放| 久久九九免费视频| 天天做天天爱综合| 色情久久久| 99热99艹在线观看| 五月婷婷六月丁香综合| 99啪视频在线观看| 五月婷婷天| 九九热在这里只有精品| 久久伦乱| 日本精品人妻无码77777| 免费视频无码| 五月激情精品视频| 免费看无码视频A级| 五月婷色| 色呦呦美女| 五月婷婷六月激情在线| 久久久久久久久99精品| 国产精品18久久久| 久久99综合网| 天天狠狠插| 婷婷色情网| 男人的天堂婷婷色五月| 婷婷九月色| 五月天婷婷丁香社区| 久久久久久久综合狠狠综合| 国产日韩欧美| 99免费视频| 26UUU精品一区二区c〇m| 99色热视频| 67194线路二在线观看| 婷婷五月天激情小说| 久热视频A.| 日本视频欧美观看免费| 婷婷五月天激情网| 国产超碰在线| 天堂草在线看www| 丁香五月色综合色播五月| 亚洲免费在线观看岛国| 九九综合| 色色色在线观看| 九九精品在线观看视频6| 成人精品一区二区三区四区五区 | 国产99久久久| 亚洲激情免费视频观看| 婷婷五月综合激情小说| 成片免费播放| 成人Av在线大片| 日韩野外 无套| www.五月天婷婷| 成人做爰A片免费看网站找不到了 噼里啪啦在线观看免费完整版视频 | 超碰人人摸AV| 夜夜躁爽日日| 午夜色婷婷| 另类激情首页| 丁香六月亭亭久久综合| 99亚洲综合| 婷婷五月天成人五月天| 久久精品系列| 亚洲天堂无码| 7777久久亚洲中文字幕| 激情五月婷婷视频| 91色五月| 婷婷五月天奸女| 天天射综合网天天插| 婷婷丁香成人在线视频| 欧美极品999| 玖玖国产视频一区| 《丁香激情综合久久伊人久久》影视在线观看 -高清预告手机免费播放 -三妹影院 | 色综合九九| 99热99久久| 亚洲色频| 婷婷娌伦网| 成人开心五月天| 久久a热| 午夜色丁香| 久久久久久久久人妻| 亚洲人人操BD| 丁香五月婷婷激情中文| 热久久视频99| 九九综合久久| 婷婷色五月偷拍| 亚洲综合网激情五月天| 婷婷久久网| 日本综合色图| 99在线观看这里都是精品| 狠狠操之狠狠操| renre人人操国产超碰在线| 五月色婷婷综合丁香精品无遮挡| 99视频在线观看视频| 婷婷久久免费看| 五月婷久久在线| 精品三区影院| 另类综合色| 色丁香五月| 九九热99热| 五月丁香五月婷婷| 久久精品A片777777| 尤物一区二区| 五月丁香趴趴| 色综合久久8| 在线99精品| 久热超碰| 一本久久亚洲五月婷婷| 色色免费网战视频| 五月丁香六月在线| 中文字幕永久免费| 99热这里精品| 激情综合网激情五月丁香五月俺也去| 五月天婷婷丁香成人网| 99色日本| 丁香影院五月综合| 色综合中文色综合网| 再綫Av免费視品| 婷婷大美在线| 天天干天天色综合| 国产成人av在线| 强辱丰满人妻HD中文字幕| 久久五月婷综合| 欧洲S级在线观看| 操人无码| 99精品22| 99综合自拍| 精品一二三区久久AAA片| www.色婷婷.com| 碰碰碰97免费精彩视频| 色婷婷丁香网| 日日操,夜夜爽| 五月婷婷欧美| 欧美成人AAA片一区国产精品 | 97碰碰电影| 久久激情视频99| 思思精品热在线| 九九热在线视频观看| 五月丁香六月天| 超级碰人人操人人干| 五月丁香六月婷婷啪啪| 婷婷开心综合人妻小说网址| 五月丁香六月婷婷成人电影| 婷婷五月综合激情| 欧美色偷偷大香| 丁香五月天色综合| 激情久久天天| 亚洲黄色影视| 精品操逼一区二区| 九九久久综合| xx人人xx| 极品少妇XXXX精品少妇偷拍| 色九九七七| 深爱激情五月天色婷婷| 九九色色网| 丁香97综合| 丁香五月综合久久八| 99热这里都是精品| 亚洲情综合五月天| 久草婷妨| 天天爽天天爽天天爽天天爽天天爽天天爽天天 | 五月丁香啪啪网| 丁香五月色网| 国产一级婬片毛片| 色五月婷婷老师| 丁香五月天婷婷91| 亚洲、热| 99热久| 成人电影在线免费试看| 婷婷精品性性性性性性性| 久久丁香五月婷婷| 激情黄色小说色五月| 99热这里只有是亚洲国产| 99精品视频在线观看| 婷婷激情综合| 婷婷六月久久综合导航| 激情涩播| 超碰三级秋霞| 五月丁香婷婷色| 婷婷丁香花五月天| 这里只有久久精99| 色色亚洲99com| 99色啊| 欧洲色| 婷婷六月丁香激情| 五月天久久综合| 婷婷五月天精品| 五月天婷婷高清无码| 98国产精品综合一区二区三区| 久热只有这里有精品| 婷婷五月综合网| 日本久久精品18| 五月婷婷真爱激情网| 色婷婷精品视频在线播放| 伊人9999| 色色欧美色色| 伊人丁香婷婷东京| 9+1视频网址| 99热20| 无码激情AAAAA片-区区| 开心六月丁香五月婷婷| 色五月av| 日日骑夜夜撸| 亚洲精品视频在线播放| 狠狠夜夜五月丁香| 久久综合五月天| 久热2025无码| 91九九| 五月激情婷婷色| 五月丁香婷婷五月色| 婷婷五月丁香高清无码| 超碰成人黄色网| 五月第四色|