我对websockets很新,并且一直试图将python与autobahn一起使用并绞死以连接到多个套接字,然后对来自每个不同套接字的数据执行不同的操作。
最后,我将有3到4个不同的处理函数和最多10-15个websocket连接。
我想将一个函数传递给协议,用于分析返回的数据。我遇到的问题是我可以想办法访问WebSocketClientProtocol的“onMessage()”方法的唯一方法是为类而不是实际对象设置,所以我坚持使用一个数据处理函数对于所有的websockets。
下面的代码示例。
from autobahn.websocket import WebSocketClientFactory, WebSocketClientProtocol
from twisted.internet import reactor, ssl
# message processing methods
def method1(self, data):
print 'Using Method 1.'
def method2(self, data):
print 'Using Method 2.'
# factory and protocol classes
class myFactory(WebSocketClientFactory):
def clientConnectionLost(self, connector, reason):
connector.connect()
class myWS(WebSocketClientProtocol):
def initialize(self, url, data_fcn):
self.factory = myFactory(url)
self.factory.protocol = myWS
# !!! set in class, not object !!!
self.factory.protocol.data_fcn = data_fcn
def onMessage(self, msg, binary):
self.data_fcn(msg)
def onClose(self, a, b, c):
reactor.stop()
reactor.disconnectAll()
def kill(self):
self.transport.loseConnection()
reactor.stop()
reactor.disconnectAll()
if __name__ == '__main__':
# websocket topics unique
topic_ids = [ '3395',
'3563',
'3562' ]
# data processing functions can repeat
data_process_fcns = [ method1,
method2,
method1 ]
for topic, func in zip(topic_ids, data_process_fcns):
url = 'wss://mywebsocket.com/feed?topic_id[]=' + topic
ws = myWS()
ws.initialize(url, func)
reactor.connectSSL(ws.factory.host, ws.factory.port, ws.factory, ssl.ClientContextFactory())
reactor.run()
我目前的解决方案是为我想要使用的每个数据处理函数创建一个类。所以,对于方法1,我有
class myWS_method1(WebSocketClientProtocol):
与
def onMessage(self, msg, binary):
method1(msg)
和我想要使用的每种数据处理方法的类似类。
希望找到一个更优雅的解决方案,让我可以重复使用一个类。
谢谢,
答案 0 :(得分:3)
在Twisted中你几乎没有自己构建协议,它是工厂的责任。我有这样的事情:
class myFactory(WebSocketClientFactory):
def __init__(self, url, data_processing):
WebSocketClientFactory.__init__(self, url)
# here you could have passed whatever parameters
# later allow you to build up the protocol instance
self._data_processing = data_processing
def buildProtocol(self, addr):
# Use this method to control the creation of the
# protocol instance.
# You can either build a protocol here and inject
# data_func, or use different protocol class type.
protocol = myWs()
protocol.data_func = self._data_processing
return protocol
然后,连接的循环看起来像:
for topic, func in zip(topic_ids, data_process_fcns):
url = 'wss://mywebsocket.com/feed?topic_id[]=' + topic
factory = myFactory(url, func)
reactor.connectSSL(factory.host, factory.port, factory, ssl.ClientContextFactory())