comet學習(二)cometd框架研究:交互流程

最近工做中須要用到基於comet技術的服務端推技術實現一個相似與聊天的東東,研究了下cometd框架。寫了一個簡單的demo,基於此demo,跟蹤了下源碼,瞭解一些客戶端與服務端的交互流程。服務器

 

 

服務端如何實現和初始化就不說了,想重點說的是服務端初始化後,客戶端發起鏈接後的交互流程:併發

 

1. 首先客戶端和服務端交互採用的Bayeux協議。框架

2. 客戶端向服務端 (/meta/handshake頻道上) 發起握手請求。Bayeux協議要求,一個新的客戶端發送的第一條消 息是一個握手信息。
3. 服務端收到握手請求,BayeuxServer創造了一個半服務器對象的實例(一個ServerSession)。服務端處理完握手請求後,發送響應給客戶端。post

 

4. 客戶端收到服務端處理握手請求的響應,若是它是成功,接下來要作兩件事情:設計

    a.向服務端發起訂閱服務的請求。對象

    b.開始與服務端的心跳機制,來交換鏈接的信息。接口

5. 以實現的demo爲例,服務端再啓動時初始化了兩個服務頻道ip

   (1./service/privatechat 2./service/joinlisten )這兩個頻道均爲自定義頻道(其實就是兩個http接口),須要寫代碼實現業務邏輯。源碼

6. 客戶端向服務端發起訂閱 /service/privatechat 服務,此服務用來實現用戶之間的聊天。io

 

   如clientA訂閱了此服務,當clientB向clientA發送聊天信息時,服務端會當即採用comet推送機制,將聊天信息推送給clientA

 

7. 開始心跳機制。

8. 心跳機制(在使用http傳輸時,cometd使用的是http傳輸),也被稱爲「長輪詢」。

 

9. 心跳機制,容許客戶端檢測服務器是否關閉了,並容許服務端檢測客戶端是否關閉了。

 

10. 客戶端和服務器之間的鏈接的消息一直都有,直至任何一方決定中斷併發送一個
disconnect 的消息(發送/meta/disconnect 斷開通道消息)

 

心跳機制先講到這裏,後續詳細再說。

11. 此時客戶端能夠向服務端/service/joinlisten 頻道發送請求,向服務端加入聊天,此接口爲服務端自定義的接口,

     客戶端須要調用此接口,加入聊天,服務端記錄下客戶端信息,相似於登陸。

 

12. 此時全部初始化工做都已準備完畢,客戶端之間就能夠任意發送聊天信息了。

 

13.comed的設計有一處巧妙之處:

 

     你們都知道http是請求響應模式,也就是一次請求對應一次響應,服務端推送信息,是沒有客戶端請求的,

 

這樣就破壞了http的交互模式,comed的實現機制是,客戶端向服務端發起心跳請求,服務端會掛起這個請求,先不迴響

應,當達到心跳時間30秒再回響應,客戶端收到響應當即再次發起心跳請求,也就是說服務端會一直掛起一個沒有處理的心跳請求,當服務端有信息須要推送給客戶端時,會把以前掛起的心跳請求的響應和推送的信息做爲一個響應消息包,推送給客戶端(也能夠理解爲把以前掛起的響應回給客戶端),這樣就沒有說是無故端的多了推送這種機制,更好的遵循了http請求,響應的規範。

 

××××××××××××××××××××××××××××××

如下是跟蹤demo的交互消息包:

1.客戶端向 /meta/handshake 發送握手請求信息。
  採用post請求[{"id":"1","supportedConnectionTypes":["long-polling"],"channel":"/meta/handshake","version":"1.0"}]
                            
2.服務端收到請求後 返回響應:
  [{"id":"1","minimumVersion":"1.0","supportedConnectionTypes":["callback-polling","long-polling"],"successful":true,"channel":"/meta/handshake","clientId":"21541woc90dqi918d826hcb0bpy","version":"1.0"}]

  客戶端根據successful 判斷是否握手成功,
 
3.客戶端向 /service/privatechat 發送訂閱聊天監聽請求。
  [{"id":"2","subscription":"/service/privatechat","channel":"/meta/subscribe","clientId":"21541woc90dqi918d826hcb0bpy"}]

4.服務端收到請求後 返回響應:
  [{"id":"2","subscription":"/service/privatechat","successful":true,"channel":"/meta/subscribe"}]

  客戶端根據successful 判斷是否訂閱成功,

5.客戶端向 /meta/connect 發送第一次心跳請求
   [{"id":"3","connectionType":"long-polling","advice":{"timeout":0},"channel":"/meta/connect","clientId":"21541woc90dqi918d826hcb0bpy"}]
    
6.服務端收到請求後返回相應:
   [{"id":"3","successful":true,"advice":{"interval":0,"reconnect":"retry","timeout":30000},"channel":"/meta/connect"}]

7.後續的心跳請求響應與第一次稍稍有區別:
    [{"id":"5","connectionType":"long-polling","channel":"/meta/connect","clientId":"21541woc90dqi918d826hcb0bpy"}]
    [{"id":"5","successful":true,"channel":"/meta/connect"}]

8.向/service/privatechat 發送聊天信息請求:     [{"id":"38","data":{"peer":"gaolp","chat":"hello world!","user":"gaolp"},"channel":"/service/privatechat","clientId":"21541woc90dqi918d826hcb0bpy"}]     [{"id":"38","data":{"scope":"private","chat":"hello world!","user":"gaolp"},"channel":"/service/privatechat"},{"id":"38","successful":true,"channel":"/service/privatechat"}]

相關文章
相關標籤/搜索