2011-07-27 40 views
4

如何在必要時實現可以將消息「推送」給客戶端的系統? 基本上,我需要的是從Python服務器將文本「推送」到Python客戶端的能力。然後文本將被解析爲將在客戶端處理的動作(一旦收到「動作文本」,我已經知道如何做這件事)。 我可以每隔幾秒鐘檢查一次正在等待的新「動作文本」 - 這只是我認爲它不可靠並可擴展到數千個客戶端。實時的事情在這裏非常重要。在Python中將消息推送到客戶端

有什麼建議嗎?

+0

我傾向於傾向於扭曲這種工作。 – Xavier

回答

2

我建議具有每個客戶端建立套接字連接到服務器。每個客戶端都可以運行一個線程,嘗試阻塞從套接字讀取(將其置於後臺線程中),以便在套接字可用時從套接字中獲取信息。然後,每當服務器寫入該套接字時,客戶端應該立即得到它。客戶端的連接應該子類telnetlib.telnet imho,因爲它提供了一種方便的read_until方法。這樣的事情可能是這樣的:

class RPCConnection(object, Telnet): 
    def __init__(self, host = 'localhost', port = 9198, auto = True): 
    Telnet.__init__(self) 

    self.host, self.port, self.connected = host, port, False 

    if auto: 
     self._connect() 

    def _connect(self): 
    self.open(self.host, self.port) 

    self.connected = True 

    def _disconnect(self): 
    self.close() 

    self.connected = False 

    def _send(self, dict): 
    self.write(json.dumps(dict)) 

    def _recv(self): 
    resp = self.read_until('\n') 

    try: 
     return json.loads(resp) 
    except Exception, e: 
     print e 
     print resp 
7

您可以使用redis發佈訂閱模型more here

Redis具有很高的可擴展性和快速性。

實施例:(來自https://github.com/andymccurdy/redis-py/blob/master/tests/pubsub.py

import redis 
import unittest 

class PubSubTestCase(unittest.TestCase): 
    def setUp(self): 
     self.connection_pool = redis.ConnectionPool() 
     self.client = redis.Redis(connection_pool=self.connection_pool) 
     self.pubsub = self.client.pubsub() 

    def tearDown(self): 
     self.connection_pool.disconnect() 

    def test_channel_subscribe(self): 
     self.assertEquals(
      self.pubsub.subscribe('foo'), 
      ['subscribe', 'foo', 1] 
      ) 
     self.assertEquals(self.client.publish('foo', 'hello foo'), 1) 
     self.assertEquals(
      self.pubsub.listen().next(), 
      { 
       'type': 'message', 
       'pattern': None, 
       'channel': 'foo', 
       'data': 'hello foo' 
      } 
      ) 
     self.assertEquals(
      self.pubsub.unsubscribe('foo'), 
      ['unsubscribe', 'foo', 0] 
      ) 

    def test_pattern_subscribe(self): 
     self.assertEquals(
      self.pubsub.psubscribe('fo*'), 
      ['psubscribe', 'fo*', 1] 
      ) 
     self.assertEquals(self.client.publish('foo', 'hello foo'), 1) 
     self.assertEquals(
      self.pubsub.listen().next(), 
      { 
       'type': 'pmessage', 
       'pattern': 'fo*', 
       'channel': 'foo', 
       'data': 'hello foo' 
      } 
      ) 
     self.assertEquals(
      self.pubsub.punsubscribe('fo*'), 
      ['punsubscribe', 'fo*', 0] 
      ) 
+1

+1用於暗示Redis,而不是實現您自己的套接字流 –

+0

+1給Redis,我認爲這是比@ g.d.d.c更好的解決方案 – Mark

相關問題