2015-03-01 11 views
5

Desidero chiamare il metodo sendMessage dall'esterno della classe MyServerProtocol e inviare un messaggio ai client connessi. Io uso threading per fare questo.sendMessage dall'esterno in autostrada in esecuzione in thread separato

Quando uso di questo codice:

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') 

questo errore si verifica:

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

Se provo a commentare la riga connection.send('test'), questo errore si verifica:

TypeError: 'NoneType' object is not iterable 

Cosa è il problema con il mio codice?

Sto facendo questo nel modo giusto? O c'è un altro modo per inviare messaggi ai client al di fuori della classe del protocollo?

Grazie.

+0

Does self.factory esiste quando si chiama send? Prova a mettere un sonno tra start() e send() e controlla. Inoltre, usa un debugger. – Raito

+0

Hai mai capito come si fa? Sto avendo lo stesso problema. – someuser

risposta

0

add self.factory al vostro "init (self):" vedi sotto:

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') 
+0

Questa filettatura gestisce anche più connessioni di pari? – hietpasd

3

è [c'è] un altro modo per inviare un messaggio clienti al di fuori della classe del server?

Faccio qualcosa del genere per inviare un messaggio. Io uso twisted per eseguire la mia app 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'}) 

Non so se è nel modo giusto ™, ma funziona bene per me.

Problemi correlati