2014-09-24 79 views
0

我正在Delphi中開發一個消息系統。我在我的客戶端應用程序中使用我的服務器應用程序中的idTcpServer和idTcpClient。客戶端應用程序每10秒鐘ping服務器以查看連接是否處於活動狀態,並通知服務器將用戶的狀態設置爲聯機狀態。並且用戶也可以將消息發送給他的聯繫人。所有這些請求之後,我發送請求後立即通過socket.readln命令獲得服務器的響應。例如ping服務器:Delphi tcpServer異步請求

TcpClient.socket.writeln('i am online'); 
if TcpClient.socket.readln = 'ok' then 
    begin 
    {commands} 
    end; 

我還使用長輪詢檢查新消息。我從tcpClient發送'check for new messages ' + timestamp,然後在服務器上,我檢查數據庫中的新消息是否比我在While循環中收到的時間戳更新,因此當有新消息時,循環會中斷並向客戶端發送通知。

但是這個系統不適合我。有時,當客戶端應用程序正在ping服務器時,我會收到針對checking for new messages的響應。

我已經開發了相同的系統在PHP中沒有問題。但這裏一定有問題。

我認爲它不是異步的。我該怎麼辦?

回答

1

關於check for new messages請求,服務器不應循環等待新消息到達。請求時或者沒有可用的新消息。獲取請求,執行查詢,報告結果,然後繼續。客戶端可以定期發送新的check for new messages請求。或者,讓客戶端一次告訴服務器它想要新消息,然後服務器可以在到達服務器時實時向客戶端推送新消息,而不是輪詢它們(類似於IMAP的IDLE命令)。

我建議你重新設計你的通信協議以便異步運行。大多數現代IM服務是異步的。當客戶發送請求時,不要期待立即回覆。讓客戶轉移到其他方面。讓它運行一個單獨的定時器/線程來讀取所有入站數據。當答覆到達時,客戶可以採取行動。如果需要,在請求中包含一個標識符,以便在回覆中回顯,以便客戶端可以跟蹤它發送的請求。這也允許服務器在其末端使用異步處理,因此如果請求需要很長時間才能運行,服務器可以將其推送到另一個線程/進程並在此期間繼續處理其他請求。準備好後發送最終答覆。

+0

感謝您的詳細解答。我搜索了一下「使用tcpServer在delphi中推送消息」。我沒有找到好的例子。你能否給我一些在線參考。我認爲在我的服務器應用程序中,我應該將'idcontext'的數據保存到內存中,並將新的消息通知發送給它。它是否正確? – Agha 2014-09-25 13:40:21