2010-07-02 26 views
2

我正在用indy 10(阻塞模式)編寫一個簡單的客戶端/服務器聊天程序,並且有一個問題,我該如何管理連接?例如,想象一個在服務器上聯機的用戶,我們必須爲將來的請求建立連接隧道。換句話說,當一個用戶在線時,服務器應該不需要用戶名和密碼以備將來的用戶請求。並且這將是我們在用戶來到時創建的隧道。我如何管理Indy中的連接? (Delphi)

我們如何管理連接?

[對不起,我的英語不好]如果你不能理解我,請告訴我發一個新的貼子。

謝謝

回答

3

對於問題中描述的場景,並沒有太多管理要做。爲了避免每次請求都需要重新進行身份驗證,只需即可關閉連接。在聊天服務器中,特別是每個參與者很可能建立連接,然後在聊天期間繼續使用相同的連接。

Indy服務器對象已經保存了其打開連接的列表,因此當您想要將聊天消息廣播給其他參與者時,您可以遍歷該列表。

+1

寫的同意的。如果您需要在請求之間保留自定義數據(如身份驗證詳細信息),則可以將每個連接信息存儲在TIdPeerThread.Data(Indy 9和更早版本)和TIdContext.Data(Indy 10)屬性中。只要連接保持打開狀態,只需要爲每個客戶端收集並存儲一次該信息。如果客戶端斷開並重新連接請求(如HTTP),則必須手動跟蹤來自一個連接的信息並將其應用到下一個連接。 – 2010-07-02 19:16:49

+0

謝謝!好答案 。最後,您提供給我什麼方式來管理連接和會話ID以最少的處理?我認爲我們必須將當前的Acontext-Index作爲會話ID發送到客戶端,並在將來的請求中收到會話ID後,我們將從中提取Acontext(連接)索引並繼續與此隧道進行通信。不是嗎? – Kermia 2010-07-02 19:32:53

+0

不,Kermia。連接關閉後,上下文對象被銷燬。既然你已經接受了這個答案,那麼不需要一個會話,*本身*。相反,*連接是會話*。客戶端不需要被服務器告知任何事情,因爲只要客戶端維持開放連接,它就已經擁有了它所需要的一切。服務器還會繼續瞭解連接,因此在Indy事件處理程序中,您將自動獲得正確的上下文對象,以查看事件發生的任何連接。 – 2010-07-02 19:50:16

0

一個選擇是在服務器端創建一個唯一的會話ID(或「標記」),例如一個GUID,如果在,而且在每一個請求,客戶端包括客戶端登錄這個令牌。

服務器將維護客戶端會話和關聯會話數據的列表,並在該列表中查找該令牌。

即使客戶端暫時與Internet斷開連接,但仍然知道其令牌,應用程序可以重新連接並繼續與服務器進行會話。

+0

感謝您的回覆,但想象一下,有10,000個在線用戶,每個用戶每秒向服務器發送10條消息。最後,我們將在一秒鐘內完成100,000個會話ID檢查。這將是服務器致命的! – Kermia 2010-07-02 13:50:41

+0

當我閱讀'一個簡單的聊天程序'時,我沒有想到10,000個用戶每100毫秒都發送一條消息:) – mjn 2010-07-02 13:56:37

+0

哦,你說得對:D。但如果我們想用這種方式來做更大的項目呢?可能嗎 ?或者你提供另一種方式? 謝謝mjustin :) – Kermia 2010-07-02 14:59:56

1

我認爲每秒100000次檢查將會是比擁有10000個永久性TCP連接更耗資源的事情。無論如何,你需要處理這些100000個命令,所以這些檢查不會是瓶頸。

嘗試使用UDP消息。例如,大多數MMO遊戲同時使用TCP和UDP連接。 TCP僅用於關鍵數據,UDP用於任何其他數據。在你的情況下,UDP似乎是可以接受的。客戶端可以發送帶有一些自動增量ID的UDP數據包,並且服務器可以定期發送它未收到的ID列表,以便客戶端可以重新發送它們。