java長輪詢

在服務端向頁面主動推送消息的業務場景下,有長輪訓和websocket兩種思路。

springboot 和websocket使用:https://blog.csdn.net/u014203449/article/details/102902078

現在看看長輪詢:

 

設想一個業務場景:A用戶打開頁面,要求實時刷新數據,B用戶操作新增數據,A頁面刷新。

1.頁面

長輪詢的做法是,A用戶打開頁面,就請求一個接口,js ajax請求時設置一個超時時間,比如60s。

 $.ajax({
  url:'',  //請求的URL
  timeout : 60000, //超時時間設置,單位毫秒
  type : 'get',  //請求方式,get或post
  data :{},  //請求所傳參數,json格式
  dataType:'json',//返回的數據格式
  success:function(data){ //請求成功的回調函數
    alert("成功");
  },

2.接口

而接口中,判斷數據是否有變化,如果有變化直接將數據返回,如果沒有變化,將線程掛起60s,60s內有變化就返回數據,無變化返回空。

線程掛起可以用sleep 或者LockSupport.park 方法將其堵塞。

3.打斷阻塞

但堵塞後如何能發現數據變化,從而返回數據呢?因爲是另一個用戶B線程進行操作導致的數據變化。

1.輪詢。可以在接口中循環sleep 幾秒,去查詢數據是否發生變化。

2.B用戶線程操作後,可以找到A用戶的長輪詢線程,然後進行打斷。A用戶線程寫個判斷打斷邏輯,如果打斷標誌爲ture,就查詢數據返回。

B線程如何找到A線程呢?可以設置一個全局線程安全集合,比如CopyOnWriteArraySet,把線程放進去。

4.下一次輪詢

而js 在接口響應後,繼續發起一次請求,監聽下一次數據的變化。

5.長輪詢案列

正好看到了Apollo配置中心,配置中心服務端如何通知客戶端配置發生了變化,這就用到了長輪詢。

Apollp的地址:https://github.com/ctripcorp/apollo/wiki/Apollo%E9%85%8D%E7%BD%AE%E4%B8%AD%E5%BF%83%E8%AE%BE%E8%AE%A1#21-%E9%85%8D%E7%BD%AE%E5%8F%91%E5%B8%83%E5%90%8E%E7%9A%84%E5%AE%9E%E6%97%B6%E6%8E%A8%E9%80%81%E8%AE%BE%E8%AE%A1

裏面寫到了:

  1. 客戶端會發起一個Http請求到Config Service的notifications/v2接口,也就是NotificationControllerV2,參見RemoteConfigLongPollService
  2. NotificationControllerV2不會立即返回結果,而是通過Spring DeferredResult把請求掛起
  3. 如果在60秒內沒有該客戶端關心的配置發佈,那麼會返回Http狀態碼304給客戶端
  4. 如果有該客戶端關心的配置發佈,NotificationControllerV2會調用DeferredResult的setResult方法,傳入有配置變化的namespace信息,同時該請求會立即返回。客戶端從返回的結果中獲取到配置變化的namespace後,會立即請求Config Service獲取該namespace的最新配置。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章