欧美一区二区三区老妇人-欧美做爰猛烈大尺度电-99久久夜色精品国产亚洲a-亚洲福利视频一区二区

數(shù)據(jù)實時更新解決方案(長輪詢以及WebSocket)-創(chuàng)新互聯(lián)

前端如何實時獲得后端不斷更新的數(shù)據(jù)?最容易實現(xiàn)的短輪詢有如下優(yōu)缺點。優(yōu)點:開發(fā)簡單。缺點:無用請求過多并卻不能保證數(shù)據(jù)的實時性。
如果對于數(shù)據(jù)要求較高,這個時候短輪詢就可以pass了。

成都創(chuàng)新互聯(lián)公司主營惠濟網(wǎng)站建設(shè)的網(wǎng)絡(luò)公司,主營網(wǎng)站建設(shè)方案,成都App定制開發(fā),惠濟h5小程序制作搭建,惠濟網(wǎng)站營銷推廣歡迎惠濟等地區(qū)企業(yè)咨詢

下面我來介紹2種稍微高大上一點的方法,哈哈哈哈

一. Long Polling長輪詢解決方案

什么是長輪詢?客戶端發(fā)起請求后,服務(wù)端發(fā)現(xiàn)當前沒有新的數(shù)據(jù),這個時候服務(wù)端沒有立即返回請求,而是將請求掛起,在等待一段時間后(一般為30s或者是60s),發(fā)現(xiàn)還是沒有數(shù)據(jù)更新的話,就返回一個空結(jié)果給客戶端。客戶端在收到服務(wù)端的回復后,立即再次向服務(wù)端發(fā)送新的請求。這次服務(wù)端在接收到客戶端的請求后,同樣等待了一段時間,這次好運的是服務(wù)端的數(shù)據(jù)發(fā)生了更新,服務(wù)端給客戶端返回了最新的數(shù)據(jù)。客戶端在拿到結(jié)果后再次發(fā)送下一個請求,如此反復。

實現(xiàn)過程如下

//polling.js==>使用node polling.js啟動服務(wù)器
const http = require('http')
const url = require('url')
const events = []//后端不斷變化的數(shù)據(jù)

let timers = new Set()
let subscribers = new Set()// 當前掛起的請求

const EventProducer = () =>{
  const event = {
    id: Date.now(),
    timestamp: Date.now()
  }
  events.push(event)
  
  // 數(shù)據(jù)發(fā)生變化,通知所有掛起的請求,將變化的最新數(shù)據(jù)返回
  subscribers.forEach(subscriber =>{
    subscriber.resp.write(JSON.stringify(events.filter(event =>event.timestamp >subscriber.timestamp)))
    subscriber.resp.end()
  })
  // 此時所有掛起的請求已經(jīng)處理完畢,清空subscribers
  subscribers.clear()
  // 取消請求的超時回調(diào)
  timers.forEach(timer =>clearTimeout(timer))
  timers.clear()  // 重置timers
}

// 10秒生成一個事件
setInterval(() =>{
  EventProducer()
}, 10000)

const server = http.createServer((req, resp) =>{
  const urlParsed = url.parse(req.url, true)
  resp.setHeader('Access-Control-Allow-Origin', '*')
  resp.setHeader('Origin', '*')
  if (urlParsed.pathname == '/list') {
    // 發(fā)送服務(wù)端現(xiàn)存事件
    resp.write(JSON.stringify(events))
    resp.end()
  } else if (urlParsed.pathname == '/subscribe') {
    const timestamp = parseInt(urlParsed.query['timestamp'])
    const subscriber = {
      timestamp,
      resp
    }
    // 新建的連接掛起來
    subscribers.add(subscriber)
    // 30s超時,自動關(guān)閉連接
    const timer = setTimeout(() =>{
      resp.end()
      timers.delete(timer)
    }, 30000)
    
    // 客戶端主動斷開連接
    req.on('close', () =>{
      subscribers.delete(subscriber)
      clearTimeout(timer)
    })
    timers.add(timer)
  }
})
server.listen(8090, () =>{
  console.log('server is up')
})
const fetchLatestEvents = async (timestamp) =>{
        const body = await fetch(`http://localhost:8090/subscribe?timestamp=${timestamp}`)
        if (body.ok) {
            const json = await body.json()
            return json
        } else {
            console.error('failed to fetch')
        }
    }

    const listEvents = async () =>{
        const body = await fetch(`http://localhost:8090/list`)
        if (body.ok) {
            const json = await body.json()
            return json
        } else {
            console.error('failed to fetch')
        }
    }
    var timestampRef = { timestamp: 0 }
    var eventsRef = []
    const fetchTask = async () =>{
        if (timestampRef.timestamp === 0) {
            // 初次加載
            const currentEvents = await listEvents()
            timestampRef.timestamp = currentEvents[currentEvents.length - 1].timestamp
            eventsRef = [...eventsRef, ...currentEvents]
        }
        //注意latestEvents數(shù)據(jù)是后端新生成的數(shù)據(jù),前端需要自己拼上老數(shù)據(jù)
        const latestEvents = await fetchLatestEvents(timestampRef.timestamp)
        if (latestEvents && latestEvents.length) {
            timestampRef = latestEvents[latestEvents.length - 1]
            eventsRef = [...eventsRef, ...latestEvents]
        }
    }
  function start() {
        fetchTask()
            .catch(err =>{
                console.error(err)
            }).finally(() =>{
                // 觸發(fā)下次加載
                start()
            })
    }
    start()

值得注意的是,這個時候,我們打開瀏覽器的調(diào)試工具可以發(fā)現(xiàn)瀏覽器每一次發(fā)出的請求都不會立馬收到回復,而是pending一段時間后(大概是10秒)才會有結(jié)果,并且結(jié)果里面都是有數(shù)據(jù)的
在這里插入圖片描述

長輪詢優(yōu)缺點 優(yōu)點:避免了客戶端大量的重復請求。再者客戶端在收到服務(wù)端的返回后,馬上發(fā)送下一個請求,這就保證了更好的數(shù)據(jù)實時性。
缺點:服務(wù)端資源大量消耗,服務(wù)端會一直hold住客戶端的請求,這部分請求會占用服務(wù)器的資源。難以處理數(shù)據(jù)更新頻繁的情況:
如果數(shù)據(jù)更新頻繁,會有大量的連接創(chuàng)建和重建過程,這部分消耗很大。

二. WebSocket解決方案

什么是WebSocket? 客戶端和服務(wù)器之間建立一個持久的長連接,這個連接是雙工的,客戶端和服務(wù)端都可以實時地給對方發(fā)送消息。

實現(xiàn)過程如下

// websocket.js   
const WebSocket = require('ws')
const events = []
let latestTimestamp = Date.now()
const clients = new Set()//連接著的socket數(shù)組

const EventProducer = () =>{
  const event = {
    id: Date.now(),
    timestamp: Date.now()
  }
  events.push(event)
  latestTimestamp = event.timestamp
  
  // 推送給所有連接著的socket
  clients.forEach(client =>{
    client.ws.send(JSON.stringify(events.filter(event =>event.timestamp >client.timestamp)))
    client.timestamp = latestTimestamp
  })
}

// 每10秒生成一個新的事件
setInterval(() =>{
  EventProducer()
}, 10000)

// 啟動socket服務(wù)器
const wss = new WebSocket.Server({ port: 8080 })
wss.on('connection', (ws, req) =>{
  console.log('client connected')
  // 首次連接,推送現(xiàn)存事件
  ws.send(JSON.stringify(events))
  const client = {
    timestamp: latestTimestamp,
    ws,
  }
  clients.add(client)//將連接放入數(shù)組
  ws.on('close', _ =>{
    clients.delete(client)
  })
})
var timestampRef={current:0}
    var eventsRef={current:[]}
     const ws = new WebSocket(`ws://localhost:8080/ws?timestamp=${timestampRef.current}`)
    ws.addEventListener('open', e =>{
      console.log('successfully connected')
    })
    ws.addEventListener('close', e =>{
      console.log('socket close')
    })
    ws.addEventListener('message', (ev) =>{
      const latestEvents = JSON.parse(ev.data)
      if (latestEvents && latestEvents.length) {
        timestampRef.current = latestEvents[latestEvents.length - 1].timestamp
         //注意latestEvents數(shù)據(jù)是后端新生成的數(shù)據(jù),前端需要自己拼上老數(shù)據(jù)
        eventsRef.current = [...eventsRef.current, ...latestEvents]
        console.log(eventsRef)
      }
    })

你會發(fā)現(xiàn)客戶端和服務(wù)端只有一個websocket連接,它們所有的通信都是發(fā)生在這個連接上面的
在這里插入圖片描述
在這里插入圖片描述

WebSocket優(yōu)缺點
優(yōu)點:客戶端和服務(wù)端建立連接的次數(shù)少。消息實時性高。雙工通信,服務(wù)端和客戶端都可以隨時給對方發(fā)送消息。相對于長輪詢適用于服務(wù)端數(shù)據(jù)頻繁更新的場景,因為客戶端在拿到信息后不需要重新建立連接或者發(fā)送請求。
缺點:系統(tǒng)設(shè)計較復雜。某些代理層軟件(如Nginx)默認配置的長連接時間是有限制的,這個時候客戶端需要自動重連,實現(xiàn)也會比較困難。

最后簡單介紹一下另外一種方案:Server-Sent Events

什么是SSE?客戶端向服務(wù)端發(fā)起一個持久化的HTTP連接,服務(wù)端接收到請求后,會掛起客戶端的請求,有新消息時,再通過這個連接將數(shù)據(jù)推送給客戶端。這里需要指出的是和WebSocket長連接不同,SSE的連接是單向的,也就是說它不允許客戶端向服務(wù)端發(fā)送消息。
優(yōu)點:和webSocket類似,連接數(shù)少。數(shù)據(jù)實時性高。缺點:SSE長連接是單向的,不允許客戶端給服務(wù)端推送數(shù)據(jù)。和WebSocket一樣會遇到代理層配置的問題

你是否還在尋找穩(wěn)定的海外服務(wù)器提供商?創(chuàng)新互聯(lián)www.cdcxhl.cn海外機房具備T級流量清洗系統(tǒng)配攻擊溯源,準確流量調(diào)度確保服務(wù)器高可用性,企業(yè)級服務(wù)器適合批量采購,新人活動首月15元起,快前往官網(wǎng)查看詳情吧

文章題目:數(shù)據(jù)實時更新解決方案(長輪詢以及WebSocket)-創(chuàng)新互聯(lián)
分享URL:http://chinadenli.net/article22/cohhcc.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供搜索引擎優(yōu)化靜態(tài)網(wǎng)站全網(wǎng)營銷推廣關(guān)鍵詞優(yōu)化服務(wù)器托管域名注冊

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

成都網(wǎng)站建設(shè)公司