Python Autobahn Websocket服务器一次接收一个连接

时间:2018-11-21 17:57:29

标签: websocket autobahn

Autobahn使用的Python Asyncio或Twisted应该同时处理并发连接。 我遵循了有关高速公路阅读文档的很好的教程,尽管一切正常,但是服务器仅接收一个连接并处理其请求,然后再接受第二个连接。

如何确保服务器并发接收多个连接而不保留其他连接对等体?

我整天都在网上搜索,但没有成功 这是我的代码(调试时我切出了很多代码)

from autobahn.asyncio.websocket import WebSocketServerProtocol
from autobahn.asyncio.websocket import WebSocketServerFactory

class NMmapperServerProtocol(WebSocketServerProtocol):
    cmd = NMmapperWSCommandParser() # I have cut out this due to debugging

    def onMessage(self, payload, isBinary):
        """
        @payload the message
        @isBinary whether it's a binary message
        """
        try:
            offload_payload = json.loads(payload.decode("utf-8"))
            await asyncio.gather(cmd.processWSCommands(offload_payload, self))
        except Exception as e:
            raise

    def onConnect(self, request):
        """
        When we've got a peer connect to our server
        """
        try:
            #print(self)
            print(request.peer, "Has connected")
        except Exception as e:
            raise

    def onOpen(self):
        """
        We have a fully connection
        """
        try:
            # Some database action can be made from here
            print("Connection now opened")
        except Exception as e:
            raise

    def onClose(self, wasClean, code, reason):
        """
        @ the client is closing his or her
        connection
        """
        try:
            print("wasClean ", wasClean)
            print("code ", code)
            print("reason ", reason)
        except Exception as e:
            raise

    # Setters
    def setCsrftoken(self, cookie_string):
        """
        @ parse an set
        """
        self.csrftoken = self.parse_csrftoken(cookie_string)

    # Setters
    def setSession(self, cookie_string):
        """
        @ parse an set
        """
        self.session = self.parse_session(cookie_string)


if __name__=="__main__":
    if(IN_PRODUCTION):
        print("RUNNING ")
        factory = NMmapperWSServerFactory(PRODUCTION_HOST, PRODUCTION_PORT)
        factory.run_loop()
    else:
        print("Running on dev")
        factory = WebSocketServerFactory()
        factory.protocol = NMmapperServerProtocol

        loop = asyncio.get_event_loop()
        coro = loop.create_server(factory, '0.0.0.0', 9000)
        server = loop.run_until_complete(coro)

        try:
            loop.run_forever()
        except KeyboardInterrupt:
            pass
        finally:
            server.close()
            loop.close()

谢谢。

1 个答案:

答案 0 :(得分:0)

我终于按预期运行了。作为一个异步库 我必须在执行长时间运行任务的每种方法上加前缀异步

问题出在onMessage上,我不得不并行处理消息 不要阻止其他想要在此处理消息的客户端。 为此,我不得不

offload_payload = json.loads(payload.decode("utf-8"))
loop = asyncio.get_event_loop()

# Offload command processing
loop.create_task(self.processWSCommands(offload_payload, self))

这样,每条消息都被并行处理 即使在这种情况下,也请确保处理消息的方法或函数不会阻塞。

from autobahn.asyncio.websocket import WebSocketServerProtocol
from autobahn.asyncio.websocket import WebSocketServerFactory

class NMmapperServerProtocol(WebSocketServerProtocol):
    cmd = NMmapperWSCommandParser() # I have cut out this due to debugging

    async def onMessage(self, payload, isBinary):
        """
        @payload the message
        @isBinary whether it's a binary message
        """
        try:
            offload_payload = json.loads(payload.decode("utf-8"))
            loop = asyncio.get_event_loop()
            #loop.create_task(runner(10, self.peer))
            #asyncio.gather(runner(20, self.peer))

            # Offload command processing
            loop.create_task(self.processWSCommands(offload_payload, self))
        except Exception as e:
            raise

    def onConnect(self, request):
        """
        When we've got a peer connect to our server
        """
        try:
            #print(self)
            print(request.peer, "Has connected")
        except Exception as e:
            raise

    def onOpen(self):
        """
        We have a fully connection
        """
        try:
            # Some database action can be made from here
            print("Connection now opened")
        except Exception as e:
            raise

    def onClose(self, wasClean, code, reason):
        """
        @ the client is closing his or her
        connection
        """
        try:
            print("wasClean ", wasClean)
            print("code ", code)
            print("reason ", reason)
        except Exception as e:
            raise

    # Setters
    def setCsrftoken(self, cookie_string):
        """
        @ parse an set
        """
        self.csrftoken = self.parse_csrftoken(cookie_string)

    # Setters
    def setSession(self, cookie_string):
        """
        @ parse an set
        """
        self.session = self.parse_session(cookie_string)


if __name__=="__main__":
    if(IN_PRODUCTION):
        print("RUNNING ")
        factory = NMmapperWSServerFactory(PRODUCTION_HOST, PRODUCTION_PORT)
        factory.run_loop()
    else:
        print("Running on dev")
        factory = WebSocketServerFactory()
        factory.protocol = NMmapperServerProtocol

        loop = asyncio.get_event_loop()
        coro = loop.create_server(factory, '0.0.0.0', 9000)
        server = loop.run_until_complete(coro)

        try:
            loop.run_forever()
        except KeyboardInterrupt:
            pass
        finally:
            server.close()
            loop.close()