java?常規(guī)輪詢長輪詢Long?polling實(shí)現(xiàn)示例詳解
正文
長輪詢是與服務(wù)器保持持久連接的最簡單的方式,它不使用任何特定的協(xié)議,例如 WebSocket 或者 Server Sent Event。
它很容易實(shí)現(xiàn),在很多場景下也很好用。
常規(guī)輪詢
從服務(wù)器獲取新信息的最簡單的方式是定期輪詢。也就是說,定期向服務(wù)器發(fā)出請求:“你好,我在這兒,你有關(guān)于我的任何信息嗎?”例如,每 10 秒一次。
作為響應(yīng),服務(wù)器首先通知自己,客戶端處于在線狀態(tài),然后 —— 發(fā)送目前為止的消息包。
這可行,但是也有些缺點(diǎn):
- 消息傳遞的延遲最多為 10 秒(兩個(gè)請求之間)。
- 即使沒有消息,服務(wù)器也會每隔 10 秒被請求轟炸一次,即使用戶切換到其他地方或者處于休眠狀態(tài),也是如此。就性能而言,這是一個(gè)很大的負(fù)擔(dān)。
因此,如果我們討論的是一個(gè)非常小的服務(wù),那么這種方式可能可行,但總的來說,它需要改進(jìn)。
長輪詢
所謂“長輪詢”是輪詢服務(wù)器的一種更好的方式。
它也很容易實(shí)現(xiàn),并且可以無延遲地傳遞消息。
其流程為:
- 請求發(fā)送到服務(wù)器。
- 服務(wù)器在有消息之前不會關(guān)閉連接。
- 當(dāng)消息出現(xiàn)時(shí) —— 服務(wù)器將對其請求作出響應(yīng)。
- 瀏覽器立即發(fā)出一個(gè)新的請求。
對于此方法,瀏覽器發(fā)出一個(gè)請求并與服務(wù)器之間建立起一個(gè)掛起的(pending)連接的情況是標(biāo)準(zhǔn)的。僅在有消息被傳遞時(shí),才會重新建立連接。
如果連接丟失,可能是因?yàn)榫W(wǎng)絡(luò)錯(cuò)誤,瀏覽器會立即發(fā)送一個(gè)新請求。
實(shí)現(xiàn)長輪詢的客戶端 subscribe
函數(shù)的示例代碼:
async function subscribe() { let response = await fetch("/subscribe"); if (response.status == 502) { // 狀態(tài) 502 是連接超時(shí)錯(cuò)誤, // 連接掛起時(shí)間過長時(shí)可能會發(fā)生, // 遠(yuǎn)程服務(wù)器或代理會關(guān)閉它 // 讓我們重新連接 await subscribe(); } else if (response.status != 200) { // 一個(gè) error —— 讓我們顯示它 showMessage(response.statusText); // 一秒后重新連接 await new Promise(resolve => setTimeout(resolve, 1000)); await subscribe(); } else { // 獲取并顯示消息 let message = await response.text(); showMessage(message); // 再次調(diào)用 subscribe() 以獲取下一條消息 await subscribe(); } } subscribe();
正如你所看到的,subscribe
函數(shù)發(fā)起了一個(gè) fetch
,然后等待響應(yīng),處理它,并再次調(diào)用自身。
服務(wù)器應(yīng)該可以處理許多掛起的連接
服務(wù)器架構(gòu)必須能夠處理許多掛起的連接。
某些服務(wù)器架構(gòu)是每個(gè)連接對應(yīng)一個(gè)進(jìn)程,導(dǎo)致進(jìn)程數(shù)和連接數(shù)一樣多,而每個(gè)進(jìn)程都會消耗相當(dāng)多的內(nèi)存。因此,過多的連接會消耗掉全部內(nèi)存。
使用像 PHP 和 Ruby 語言編寫的后端程序會經(jīng)常遇到這個(gè)問題。
使用 Node.js 編寫的服務(wù)端程序通常不會出現(xiàn)此類問題。
也就是說,這不是編程語言的問題。大多數(shù)現(xiàn)代編程語言,包括 PHP 和 Ruby,都允許實(shí)現(xiàn)更適當(dāng)?shù)暮蠖顺绦?。只是請確保你的服務(wù)器架構(gòu)在同時(shí)有很多連接的情況下能夠正常工作。
以上就是java 常規(guī)輪詢長輪詢Long polling實(shí)現(xiàn)示例詳解的詳細(xì)內(nèi)容,更多關(guān)于java 常規(guī)輪詢長輪詢的資料請關(guān)注腳本之家其它相關(guān)文章!
- Java實(shí)現(xiàn)一個(gè)簡單的長輪詢的示例代碼
- Java servlet通過事件驅(qū)動進(jìn)行高性能長輪詢詳解
- Java?輪詢鎖使用時(shí)遇到問題解決方案
- Java?死鎖解決方案順序鎖和輪詢鎖
- Java實(shí)現(xiàn)平滑加權(quán)輪詢算法之降權(quán)和提權(quán)詳解
- Java負(fù)載均衡算法實(shí)現(xiàn)之輪詢和加權(quán)輪詢
- Java如何使用ReentrantLock實(shí)現(xiàn)長輪詢
- Java 利用DeferredResult實(shí)現(xiàn)http輪詢實(shí)時(shí)返回?cái)?shù)據(jù)接口
- 基于Rxjava實(shí)現(xiàn)輪詢定時(shí)器
- 告別無盡等待:Java中的輪詢終止技巧
相關(guān)文章
java input 調(diào)用手機(jī)相機(jī)和本地照片上傳圖片到服務(wù)器然后壓縮的方法
今天小編就為大家分享一篇java input 實(shí)現(xiàn)調(diào)用手機(jī)相機(jī)和本地照片上傳圖片到服務(wù)器然后壓縮的方法,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-08-08Java并發(fā)編程中的volatile關(guān)鍵字詳解
這篇文章主要介紹了Java并發(fā)編程中的volatile關(guān)鍵字詳解,volatile?用于保證我們某個(gè)變量的可見性,使其一直存放在主存中,不被移動到某個(gè)線程的私有工作內(nèi)存中,需要的朋友可以參考下2023-08-08利用Java工具類Hutool實(shí)現(xiàn)驗(yàn)證碼校驗(yàn)功能
這篇文章主要介紹了利用Java工具類Hutool實(shí)現(xiàn)驗(yàn)證碼校驗(yàn)功能,利用Hutool實(shí)現(xiàn)驗(yàn)證碼校驗(yàn),校驗(yàn)的Servlet與今天的第一篇是一樣的,唯一就是驗(yàn)證碼的生成是不一樣的,利用Hutool生成驗(yàn)證碼更快捷.需要的朋友可以參考下2022-10-10基于Java實(shí)現(xiàn)Redis多級緩存方案
這篇文章主要介紹了Redis多級緩存方案分享,傳統(tǒng)緩存方案、多級緩存方案、JVM本地緩存,舉例說明這些方案,具有一定的參考價(jià)值,需要的小伙伴可以參考一下2022-03-03springboot項(xiàng)目事務(wù)標(biāo)簽驗(yàn)證
本文主要介紹了springboot項(xiàng)目事務(wù)標(biāo)簽驗(yàn)證,文中通過示例代碼介紹的非常詳細(xì),詳細(xì)的介紹了不加事務(wù)標(biāo)簽和加事物標(biāo)簽的使用,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-07-07SpringCloud容器化服務(wù)發(fā)現(xiàn)及注冊實(shí)現(xiàn)方法解析
這篇文章主要介紹了SpringCloud容器化服務(wù)發(fā)現(xiàn)及注冊實(shí)現(xiàn)方法解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-08-08SpringCloud大文件分片斷點(diǎn)上傳實(shí)現(xiàn)原理
這篇文章主要介紹了SpringCloud大文件分片斷點(diǎn)上傳實(shí)現(xiàn)原理,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-05-05使用Java把文本內(nèi)容轉(zhuǎn)換成網(wǎng)頁的實(shí)現(xiàn)方法分享
這篇文章主要介紹了使用Java把文本內(nèi)容轉(zhuǎn)換成網(wǎng)頁的實(shí)現(xiàn)方法分享,利用到了Java中的文件io包,需要的朋友可以參考下2015-11-11