2013-02-23 55 views
0

有一個應用程序需要將消息發送給一羣客戶端。客戶端是用戶計算機上的應用程序,並且這些應用程序有時每次運行幾天。服務器要麼有新的指令,要麼沒有。有時兩條新指令有10分鐘,有時一小時,有時一天。消息的長度是固定的。使用套接字向客戶端發送定期消息的最佳方式

實現此目的的最佳方法是什麼?我應該讓客戶端每隔10秒輪詢一次服務器嗎?每次新客戶端連接時,我應該在服務器上創建一個新線程,並保持連接,直到有新的指令,然後將其發送給客戶端並讓客戶端創建新的連接?

或者我應該將消息推送給客戶端?我在想如何做到這一點,我想出了這個: 作爲服務器和客戶端的服務器服務器。當客戶握手時,它將地址提供給服務器。然後服務器開始充當客戶端(並且作爲服務器來顯然允許其他客戶端連接),並且保持與客戶端的連接。客戶端就像服務器一樣,等待消息。

最後一個看起來相當複雜。做這個的最好方式是什麼?來自服務器的新消息(「指令」)應該在服務器「擁有」至少15秒後到達客戶端。

順便說一下,服務器應用程序將在Windows上運行。我不確定的客戶中,但我們假設多平臺。服務器和客戶端應用程序都是用Python編寫的。

謝謝你的時間。

+0

也許xmpp協議可以給你一些想法? (http://en.wikipedia.org/wiki/XMPP) – thebjorn 2013-02-23 23:50:15

+0

@thebjorn XMPP似乎有點矯枉過正,因爲我在做什麼,我想。但我過去曾用它來通過互聯網進行溝通。 – Taoelism 2013-02-24 00:17:34

回答

0

我會讓每個客戶端打開一個到服務器的連接,然後等待任何數據被讀取。只要有消息要發佈,服務器就會寫入所有連接的客戶端。

具體來說,服務器應該是socket(),bind(),listen(),然後輸入一個accept()循環。對於接受的每個新客戶端,它應該只將已連接的套接字添加到活動客戶端列表中,而不會讀取或寫入任何內容(除非初始應用程序級別握手或身份驗證(如果適用);在這種情況下應在單獨的線程,分叉進程或非阻塞事件循環中執行握手或身份驗證,以避免慢速客戶端鎖定其他正在進行的身份驗證甚至接受循環。)

客戶端應該連接到服務器(並在適用的情況下執行握手或身份驗證),然後等待它獲得任何數據。客戶端在套接字上等待的方式傳統上使用poll()select()來完成。這些調用可以在一個單獨的線程或進程中以阻塞的方式完成;或者以非阻塞的方式,在主應用程序循環中或由定期計時器觸發。

只要服務器有消息要發佈,它就會在連接的客戶端列表上循環,對每個連接的客戶端執行消息的write()

然後,客戶端將從其當前或下一個poll()select()返回,並指示套接字具有可讀數據,並且它們將繼續到read()消息。

+0

感謝您的幫助。但爲什麼不使用'send()'和'recv()'? 'recv()'也是一個阻塞調用,並且消息具有固定大小。使用'read()'和'write()'而不是'recv()'和'write()'有什麼優勢? – Taoelism 2013-02-24 00:13:10

+0

'send()'和'recv()'用於通過UDP進行通信,UDP是無連接協議,不保證傳送。 UDP數據包可能無序地到達,多次或根本沒有到達。在你的情況下,我認爲你希望客戶端*知道*它是否仍然連接到服務器,以便它*將*儘快收到任何消息。這就是TCP連接,'read()'和'write()'的作用。 – Tobia 2013-02-24 00:23:21

+0

謝謝!我不知道。我已經讀了一些關於套接字的內容,但我沒有讀到這個。 Python Sockets HOWTO沒有提及任何有關(http://docs.python.org/2/howto/sockets.html)。你所說的正是我想要的(「客戶知道它是否仍然連接到服務器,以便它會在可用時立即收到任何消息」) – Taoelism 2013-02-24 00:38:22

相關問題