2017-03-23 50 views
0

我想在Web服務中實現長輪詢。我可以在客戶端設置足夠長的暫停時間。 我可以給中級網絡組件提示以保持響應是開放的嗎?我的意思是NAT,病毒掃描程序,反向代理或周圍的SSH隧道,可能在客戶端和服務器之間,我沒有在我的控制之下。如何保持HTTP長輪詢連接打開?

下載可能會持續數小時,但閒置連接可能會在不到一分鐘內終止。這是我想要防止的。我可以通知中間網絡一個空閒連接是我想要的,而不是因爲服務器已斷開?

如果是這樣,怎麼樣?我一直在搜索四個小時左右,但我沒有找到有關這方面的信息。

  • 我應該發送200 OK,也許一些頭,然後什麼都沒有?
  • 我必須回覆102 Processing而不是200 OK,一切都很好嗎?
  • 我應該不時發送0x16(同步空閒)字節嗎?如果是這樣,在最初的HTTP狀態碼之前或之後,在標題之前或之後?他們是否將其轉入傳輸的文件,並可能會破壞它?

Web服務/服務器使用Boost在C++中,並且返回的內容文件位於Turtle語法中。

+0

A [HTTP持續連接](https://en.wikipedia.org/wiki/HTTP_persistent_connection)也許?如果您只是閱讀HTTP 1.1規範,那麼該選項應該非常清晰。 –

+0

我打算保持*響應*打開。 (我相應地更新了我的問題。)我認爲長時間的下載可能會持續數小時,而不到一分鐘後沒有響應可能會導致超時。例如,PuTTY有一些TCP保持活動選項。我不知道這樣的事情是否也可以通過HTTP實現。 – Paramaeleon

+0

@Someprogrammerdude這並不能保證連接*和響應*將保持打開狀態。這就是爲什麼實現長輪詢的庫必須能夠在超時之後重新連接。 –

回答

0

您不能強制代理擴展它們的空閒超時,至少不能沒有管理權限。

好消息是,您可以設計您的長輪詢解決方案,使其可以從突然關閉的連接中恢復。

一個這樣的設計將是如下:

  1. 由於長輪詢通常用於事件通知(想想觀察者模式),您關聯的每個事件的序列號。
  2. 客戶端發出一個GET請求,其中包含上次看到的最後一個事件的序列號,可以是URL的一部分,也可以是cookie。
  3. 服務器維護最近事件的緩衝區。在收到來自客戶端的GET請求後,它會根據客戶端提供的序列號和序列號,檢查是否有任何緩衝事件需要發送給客戶端。如果是這樣,所有這些事件都在一個HTTP響應中發送。如果有代理希望在進一步中繼之前緩存整個響應,則該響應在此時結束。
  4. 如果客戶端是最新的,也就是說它沒有錯過任何緩存的事件,服務器將延遲其響應直到生成另一個事件。當發生這種情況時,它會作爲一個完整的HTTP響應發送。
  5. 當客戶端收到響應時,它立即發送一個新響應。當它檢測到連接已關閉時,它會創建一個新連接併發出新請求。

當使用cookie傳達客戶端看到的最後一個事件的序列號時,客戶端實現變得非常簡單。基本上你只是在客戶端啓用cookie,就是這樣。

+0

你描述的是正確的,這是我已經打算做的。我知道我無法在某個代理中欺騙一下。但是,例如,PuTTY具有一些TCP保持活動選項。我想知道是否也可以實現HTTP這樣的事情 - 以「假冒正在運行的下載」。它可能仍然會發生一些最大傳輸超時,但它應該避免無數據超時。 – Paramaeleon

+0

@Paramaeleon TCP keep-alive在這種情況下並不是非常有用,因爲'a)'你無法控制它的間隔,'b)'它不是延長連接時間,而是在你的同伴死亡時檢測到一種情況(重啓)而不通知你。儘管可能通過發送一段時間內響應的小無響應時間段來延長HTTP連接,但這種技巧在代理存在時不健壯。 –

+0

@Paramaeleon事實上,延長聯繫的另一種方式是限制您延遲迴應的時間。達到該限制時,您會發出一個空的回覆,並且客戶端會提交一個新的回覆。儘管如此,代理服務器的超時總是會被設置爲更小的值。最後,當你的系統在突然關閉的情況下強壯時,我沒有看到試圖延長連接的時間。 –