结合Asyncio Tcp Server和Tornado Web Socket

时间:2018-01-16 09:07:31

标签: python asynchronous tornado python-asyncio

我有一个连接到5 tcp客户端的asycnio tcp服务器。

import asyncio

class EchoServerClientProtocol(asyncio.Protocol):
    def connection_made(self, transport):
        peername = transport.get_extra_info('peername')
        print('Connection from {}'.format(peername))
        self.transport = transport

    def data_received(self, data):
        message = data.decode()
        print('Data received: {!r}'.format(message))

        print('Send: {!r}'.format(message))
        self.transport.write(data)

        print('Close the client socket')
        self.transport.close()

loop = asyncio.get_event_loop()
# Each client connection will create a new protocol instance
coro = loop.create_server(EchoServerClientProtocol, '127.0.0.1', 8888)
server = loop.run_until_complete(coro)

# Serve requests until Ctrl+C is pressed
print('Serving on {}'.format(server.sockets[0].getsockname()))
try:
    loop.run_forever()
except KeyboardInterrupt:
    pass

# Close the server
server.close()
loop.run_until_complete(server.wait_closed())
loop.close()

我还有一个龙卷风websocket连接到3 webbrowser。

import tornado.httpserver
import tornado.websocket
import tornado.ioloop
import tornado.web

class WSHandler(tornado.websocket.WebSocketHandler):

    clients = []

    def check_origin(self, origin):
        return True

    def open(self):
        print('New Connection Established')
        self.write_message("Connected Server...")
        WSHandler.clients.append(self)

    def on_message(self, message):
        print('Message Received: {}'.format(message))

    def on_close(self):
        print('Connection Closed...')
        WSHandler.clients.remove(self)
        del self

    @classmethod
    def write_to_clients(cls, message):
        print("Writing to Clients")
        for client in cls.clients:
            client.write_message(message)

    @classmethod
    def write_to_other_clients(cls, self_client, message):
        print("Writing to Other clients")
        for client in cls.clients:
            if  self_client != client:
                client.write_message(message)


application = tornado.web.Application([
  (r'/', WSHandler),
])



http_server = tornado.httpserver.HTTPServer(application)
http_server.listen(8888)
tornado.ioloop.IOLoop.instance().start()

现在我想把它们结合起来。这就是我想要做的事情: 我的服务器总是会听我的客户。 当数据从其中任何一个到达时,程序将使用Websocket异步发布到webbrowser。 我做了很多研究,但无法取得成功......

1 个答案:

答案 0 :(得分:2)

您可以使用龙卷风提供的bridge between asyncio and tornado

# Imports
import asyncio
import tornado.platform
# [...]

# Define Tornado application
class WSHandler(tornado.websocket.WebSocketHandler):
    clients = []
    # [...]
application = tornado.web.Application([(r'/', WSHandler)])

# Define asyncio server protocol
class EchoServerClientProtocol(asyncio.Protocol):
    def data_received(self, data):
        WSHandler.write_to_clients(data.decode())
    # [...]

# Install asyncio event loop
tornado.platform.asyncio.AsyncIOMainLoop().install()
loop = asyncio.get_event_loop()

# Create tornado HTTP server   
http_server = tornado.httpserver.HTTPServer(application)
http_server.listen(8888)

# Start asyncio TCP server
coro = loop.create_server(EchoServerClientProtocol, '127.0.0.1', 8889)
server = loop.run_until_complete(coro)

# Run forever
loop.run_forever()
# [...]