如何在必要時實現可以將消息「推送」給客戶端的系統? 基本上,我需要的是從Python服務器將文本「推送」到Python客戶端的能力。然後文本將被解析爲將在客戶端處理的動作(一旦收到「動作文本」,我已經知道如何做這件事)。 我可以每隔幾秒鐘檢查一次正在等待的新「動作文本」 - 這只是我認爲它不可靠並可擴展到數千個客戶端。實時的事情在這裏非常重要。在Python中將消息推送到客戶端
有什麼建議嗎?
如何在必要時實現可以將消息「推送」給客戶端的系統? 基本上,我需要的是從Python服務器將文本「推送」到Python客戶端的能力。然後文本將被解析爲將在客戶端處理的動作(一旦收到「動作文本」,我已經知道如何做這件事)。 我可以每隔幾秒鐘檢查一次正在等待的新「動作文本」 - 這只是我認爲它不可靠並可擴展到數千個客戶端。實時的事情在這裏非常重要。在Python中將消息推送到客戶端
有什麼建議嗎?
我建議具有每個客戶端建立套接字連接到服務器。每個客戶端都可以運行一個線程,嘗試阻塞從套接字讀取(將其置於後臺線程中),以便在套接字可用時從套接字中獲取信息。然後,每當服務器寫入該套接字時,客戶端應該立即得到它。客戶端的連接應該子類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
您可以使用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用於暗示Redis,而不是實現您自己的套接字流 –
+1給Redis,我認爲這是比@ g.d.d.c更好的解決方案 – Mark
我傾向於傾向於扭曲這種工作。 – Xavier