Python 3.x Tornado websocket服务器和websocket客户端使用AsyncIO在一个循环中同时运行

Python 3.x Tornado websocket服务器和websocket客户端使用AsyncIO在一个循环中同时运行,python-3.x,websocket,server,client,tornado,Python 3.x,Websocket,Server,Client,Tornado,我想在同一个循环中同时运行一个tornado websocket服务器和一个单独的websocket客户端,这样我就可以从单个websocket客户端接收数据,并将数据从tornado服务器发送到所有连接的客户端 我可以运行tornado服务器和websocket客户端,但tornado服务器没有响应客户端请求。我得到了类似于“等待127.0.0.1:8000的响应”的消息 我想我在异步方面遇到了问题。我假设我的websocket客户端正在阻止整个过程 有人有主意吗 谢谢 龙卷风服务器: imp

我想在同一个循环中同时运行一个tornado websocket服务器和一个单独的websocket客户端,这样我就可以从单个websocket客户端接收数据,并将数据从tornado服务器发送到所有连接的客户端

我可以运行tornado服务器和websocket客户端,但tornado服务器没有响应客户端请求。我得到了类似于“等待127.0.0.1:8000的响应”的消息

我想我在异步方面遇到了问题。我假设我的websocket客户端正在阻止整个过程

有人有主意吗

谢谢

龙卷风服务器:

import os.path
import tornado.web
import tornado.websocket
import tornado.httpserver
import asyncio
from ws_client import WebsocketClient


URL = "ws://echo.websocket.org"
tornado_connections = set()
ws_echo = None

class Application(tornado.web.Application): 
   def __init__(self):
       handlers = [
           (r"/", IndexHandler),
           (r"/ws", WsHandler)
           ]
       settings = dict(
           template_path=os.path.join(os.path.dirname(__file__), "template"), 
           static_path=os.path.join(os.path.dirname(__file__), "static"), 
       )
       tornado.web.Application.__init__(self, handlers, **settings)

class IndexHandler(tornado.web.RequestHandler): 
   def get(self):
       self.render("index_test.html")

class WsHandler(tornado.websocket.WebSocketHandler): 
   async def open(self):
       if self not in tornado_connections:
           await tornado_connections.add(self)
           await ws_echo.update_connections(connections=tornado_connections)
           print('TORNADO: client connected.')

   def on_message(self, message): 
       print(message)

   def on_close(self):
       if self in tornado_connections:
           tornado_connections.remove(self)
           print('TORNADO: client disconnected.')


async def start_tornado_server():
   app = Application()
   server = tornado.httpserver.HTTPServer(app) 
   server.listen(8000)

async def start_ws_client():
   ws_echo = WebsocketClient(url=URL, connections=tornado_connections)
   await ws_echo.connect()

async def main():
   await start_tornado_server()
   asyncio.create_task(start_ws_client())

asyncio.run(main())
import websocket
import asyncio


class WebsocketClient:
    def __init__(self, url, connections):
        self.url = url
        self.connections = connections

    def __on_open(self):
        print('Echo client connected')
        self.ws.send("Websocket rocks!")

    def __on_message(self, msg):
        print("on_messaeg: ", msg)

    def __on_close(self):
        print("Websocket closed")

    async def connect(self):
        self.ws = websocket.WebSocketApp(
            self.url,
            on_open=self.__on_open,
            on_message=self.__on_message,
            on_close=self.__on_close,
        )
        await self.ws.run_forever()

    async def disconnect(self):
        await self.ws.close()

    async def update_connections(self, connections):
        self.connections = connections
        await print("connections: ", len(self.connections))
var ws = new WebSocket("ws://127.0.0.1:8000/ws");

ws.onopen = function () {
    ws.send("Client CONNECTED");
};

ws.onmessage = function (evt) {
    document.getElementById("p1").innerHTML = evt.data;
};

ws.onclose = function () {
    console.log("Client DISCONNECTED");
};
Websocket客户端:

import os.path
import tornado.web
import tornado.websocket
import tornado.httpserver
import asyncio
from ws_client import WebsocketClient


URL = "ws://echo.websocket.org"
tornado_connections = set()
ws_echo = None

class Application(tornado.web.Application): 
   def __init__(self):
       handlers = [
           (r"/", IndexHandler),
           (r"/ws", WsHandler)
           ]
       settings = dict(
           template_path=os.path.join(os.path.dirname(__file__), "template"), 
           static_path=os.path.join(os.path.dirname(__file__), "static"), 
       )
       tornado.web.Application.__init__(self, handlers, **settings)

class IndexHandler(tornado.web.RequestHandler): 
   def get(self):
       self.render("index_test.html")

class WsHandler(tornado.websocket.WebSocketHandler): 
   async def open(self):
       if self not in tornado_connections:
           await tornado_connections.add(self)
           await ws_echo.update_connections(connections=tornado_connections)
           print('TORNADO: client connected.')

   def on_message(self, message): 
       print(message)

   def on_close(self):
       if self in tornado_connections:
           tornado_connections.remove(self)
           print('TORNADO: client disconnected.')


async def start_tornado_server():
   app = Application()
   server = tornado.httpserver.HTTPServer(app) 
   server.listen(8000)

async def start_ws_client():
   ws_echo = WebsocketClient(url=URL, connections=tornado_connections)
   await ws_echo.connect()

async def main():
   await start_tornado_server()
   asyncio.create_task(start_ws_client())

asyncio.run(main())
import websocket
import asyncio


class WebsocketClient:
    def __init__(self, url, connections):
        self.url = url
        self.connections = connections

    def __on_open(self):
        print('Echo client connected')
        self.ws.send("Websocket rocks!")

    def __on_message(self, msg):
        print("on_messaeg: ", msg)

    def __on_close(self):
        print("Websocket closed")

    async def connect(self):
        self.ws = websocket.WebSocketApp(
            self.url,
            on_open=self.__on_open,
            on_message=self.__on_message,
            on_close=self.__on_close,
        )
        await self.ws.run_forever()

    async def disconnect(self):
        await self.ws.close()

    async def update_connections(self, connections):
        self.connections = connections
        await print("connections: ", len(self.connections))
var ws = new WebSocket("ws://127.0.0.1:8000/ws");

ws.onopen = function () {
    ws.send("Client CONNECTED");
};

ws.onmessage = function (evt) {
    document.getElementById("p1").innerHTML = evt.data;
};

ws.onclose = function () {
    console.log("Client DISCONNECTED");
};
JavaScript Websocket客户端:

import os.path
import tornado.web
import tornado.websocket
import tornado.httpserver
import asyncio
from ws_client import WebsocketClient


URL = "ws://echo.websocket.org"
tornado_connections = set()
ws_echo = None

class Application(tornado.web.Application): 
   def __init__(self):
       handlers = [
           (r"/", IndexHandler),
           (r"/ws", WsHandler)
           ]
       settings = dict(
           template_path=os.path.join(os.path.dirname(__file__), "template"), 
           static_path=os.path.join(os.path.dirname(__file__), "static"), 
       )
       tornado.web.Application.__init__(self, handlers, **settings)

class IndexHandler(tornado.web.RequestHandler): 
   def get(self):
       self.render("index_test.html")

class WsHandler(tornado.websocket.WebSocketHandler): 
   async def open(self):
       if self not in tornado_connections:
           await tornado_connections.add(self)
           await ws_echo.update_connections(connections=tornado_connections)
           print('TORNADO: client connected.')

   def on_message(self, message): 
       print(message)

   def on_close(self):
       if self in tornado_connections:
           tornado_connections.remove(self)
           print('TORNADO: client disconnected.')


async def start_tornado_server():
   app = Application()
   server = tornado.httpserver.HTTPServer(app) 
   server.listen(8000)

async def start_ws_client():
   ws_echo = WebsocketClient(url=URL, connections=tornado_connections)
   await ws_echo.connect()

async def main():
   await start_tornado_server()
   asyncio.create_task(start_ws_client())

asyncio.run(main())
import websocket
import asyncio


class WebsocketClient:
    def __init__(self, url, connections):
        self.url = url
        self.connections = connections

    def __on_open(self):
        print('Echo client connected')
        self.ws.send("Websocket rocks!")

    def __on_message(self, msg):
        print("on_messaeg: ", msg)

    def __on_close(self):
        print("Websocket closed")

    async def connect(self):
        self.ws = websocket.WebSocketApp(
            self.url,
            on_open=self.__on_open,
            on_message=self.__on_message,
            on_close=self.__on_close,
        )
        await self.ws.run_forever()

    async def disconnect(self):
        await self.ws.close()

    async def update_connections(self, connections):
        self.connections = connections
        await print("connections: ", len(self.connections))
var ws = new WebSocket("ws://127.0.0.1:8000/ws");

ws.onopen = function () {
    ws.send("Client CONNECTED");
};

ws.onmessage = function (evt) {
    document.getElementById("p1").innerHTML = evt.data;
};

ws.onclose = function () {
    console.log("Client DISCONNECTED");
};
该库(或者至少是您正在使用的
run\u forever
方法)是同步的,不能与asyncio组合,除非在其自己的线程中运行它

相反,您需要一个异步websocket客户端实现,例如(或)

库(或至少您正在使用的
run\u forever
方法)是同步的,不能与asyncio结合,除非在其自己的线程中运行它


相反,您需要一个异步websocket客户端实现,例如(或)

谢谢Ben,您为我指明了正确的方向,非常有用!现在,使用异步tornado websocket客户端,应用程序可以接收websocket数据并响应请求处理程序。感谢Ben,您为我指明了正确的方向,非常有用!现在,使用异步tornado websocket客户端,应用程序可以接收websocket数据并响应请求处理程序。