来自外部的sendMessage在autobahn中运行在单独的线程中

时间:2015-03-01 22:10:02

标签: python autobahn

我想从sendMessage类之外调用MyServerProtocol方法,并向连接的客户端发送消息。我使用threading来执行此操作。

当我使用此代码时:

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

发生此错误:

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

如果我尝试注释掉connection.send('test')行,则会发生以下错误:

TypeError: 'NoneType' object is not iterable

我的代码有什么问题?

我这样做是对的吗?或者是否有另一种从协议类外部向客户端发送消息的方法?

感谢。

2 个答案:

答案 0 :(得分:3)

  

是另一种从服务器类外部发送客户端消息的方法吗?

我做这样的事情来发送消息。我使用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'}) 来运行我的网络应用。

svn info

我不知道它是否是 The Right Way ™,但对我来说效果很好。

答案 1 :(得分:0)

将self.efactory添加到“init(self):”中,如下所示:

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