SendMessage desde afuera en autobahn corriendo en un hilo separado

Quiero llamar sendMessage método sendMessage desde fuera de la clase MyServerProtocol y enviar un mensaje a los clientes conectados. Yo uso threading para hacer esto.

Cuando uso este código:

 from autobahn.twisted.websocket import WebSocketServerProtocol, WebSocketServerFactory from twisted.internet import reactor import threading class MyServerProtocol(WebSocketServerProtocol): def onConnect(self, request): print("Client connecting: {0}".format(request.peer)) def onOpen(self): print("WebSocket connection open.") def onMessage(self, payload, isBinary): if isBinary: print("Binary message received: {0} bytes".format(len(payload))) else: print("Text message received: {0}".format(payload.decode('utf8'))) self.sendMessage(payload, isBinary) def onClose(self, wasClean, code, reason): print("WebSocket connection closed: {0}".format(reason)) class Connection(threading.Thread): def __init__(self): super(Connection, self).__init__() def run(self): self.factory = WebSocketServerFactory("ws://localhost:9000", debug=False) self.factory.protocol = MyServerProtocol reactor.listenTCP(9000, self.factory) reactor.run(installSignalHandlers=0) def send(self, data): reactor.callFromThread(self.factory.protocol.sendMessage, self.factory.protocol, data) connection = Connection() connection.daemon = True connection.start() connection.send('test') 

este error ocurre:

 connection.send('test') reactor.callFromThread(self.factory.protocol.sendMessage, self.factory.protocol, data) AttributeError: 'Connection' object has no attribute 'factory' 

Si bash comentar la línea connection.send('test') , ocurre este error:

 TypeError: 'NoneType' object is not iterable 

¿Cuál es el problema con mi código?

¿Estoy haciendo esto de la manera correcta? ¿O hay otra forma de enviar un mensaje a los clientes desde fuera de la clase de protocolo?

Gracias.

¿Hay [hay] otra manera de enviar mensajes a los clientes desde fuera de la clase del servidor?

Hago algo como esto para enviar un mensaje. Yo uso twisted para ejecutar mi aplicación web.

 import json from autobahn.twisted.websocket import WebSocketServerProtocol from twisted.internet import reactor class MyProtocol(WebSocketServerProtocol): connections = list() def onConnect(self, request): self.connections.append(self) def onClose(self, wasClean, code, reason): self.connections.remove(self) @classmethod def broadcast_message(cls, data): payload = json.dumps(data, ensure_ascii = False).encode('utf8') for c in set(cls.connections): reactor.callFromThread(cls.sendMessage, c, payload) # Somewhere else MyProtocol.broadcast_message({'greeting': 'Hello world'}) 

No sé si es The Right Way ™, pero funciona bien para mí.

agregue self.factory a su “init (self):” vea a continuación:

 from autobahn.twisted.websocket import WebSocketServerProtocol, WebSocketServerFactory from twisted.internet import reactor import threading class MyServerProtocol(WebSocketServerProtocol): def onConnect(self, request): print("Client connecting: {0}".format(request.peer)) def onOpen(self): print("WebSocket connection open.") def onMessage(self, payload, isBinary): if isBinary: print("Binary message received: {0} bytes".format(len(payload))) else: print("Text message received: {0}".format(payload.decode('utf8'))) self.sendMessage(payload, isBinary) def onClose(self, wasClean, code, reason): print("WebSocket connection closed: {0}".format(reason)) class Connection(threading.Thread): def __init__(self,factory): super(Connection, self).__init__() self.factory=WebSocketServerFactory("ws://localhost:9000", debug=False) def run(self): self.factory.protocol = MyServerProtocol() reactor.listenTCP(9000, self.factory) reactor.run(installSignalHandlers=0) def send(self, data): reactor.callFromThread(self.factory.protocol.sendMessage, self.factory.protocol, data) connection = Connection() connection.daemon = True connection.start() connection.send('test')