Websocket tornado客户端对\u消息\u回调没有响应
我正在为服务器和客户机构建一个简单的应用程序,以便在构建更复杂的应用程序之前进行数据通信。这个问题的目的很简单。在这里,客户机每秒钟向服务器创建一次数据,如果从客户机收到的数据是类似“发送”的文本消息,服务器也会发回一些数据。我几乎想创建这个类似的应用程序。但它不起作用,所以我花了将近一个星期的时间来浪费我的周末 问题是,在服务器收到消息(这意味着向客户端请求消息)后,服务器似乎已按照日志发送了数据,但客户端没有响应。据我所知,我认为名为cb_receive()的回调函数应该对此做出响应 我用下面的简单应用程序创建了这个问题。请告诉我您是否擅长asyncio和tornado库。再次感谢 服务器端 客户端Websocket tornado客户端对\u消息\u回调没有响应,websocket,tornado,Websocket,Tornado,我正在为服务器和客户机构建一个简单的应用程序,以便在构建更复杂的应用程序之前进行数据通信。这个问题的目的很简单。在这里,客户机每秒钟向服务器创建一次数据,如果从客户机收到的数据是类似“发送”的文本消息,服务器也会发回一些数据。我几乎想创建这个类似的应用程序。但它不起作用,所以我花了将近一个星期的时间来浪费我的周末 问题是,在服务器收到消息(这意味着向客户端请求消息)后,服务器似乎已按照日志发送了数据,但客户端没有响应。据我所知,我认为名为cb_receive()的回调函数应该对此做出响应 我用下
请帮帮我!我不仅尝试了上面的tornado库,还尝试了WebSocket等。但它没有起作用。为什么会发生这种情况? 这是因为
run
方法中的while
循环的迭代速度比Tornado调用cbu receive
的速度快
解决这个问题的一个坏方法是在循环结束时睡一小段时间。通过这种方式,IOLoop
变得免费,可以运行其他协同路由和回调
例如:
为True时:
#其他代码。。。
产量(0.01)
如果运行客户机,则每当服务器发送消息时,都会调用cb_receive
回调
但这是一个非常糟糕的解决方案。我刚才提到它是为了让实际问题变得明显。现在,我想您知道了没有调用cb_receive
回调的原因
有什么解决办法? 发生此问题的真正原因是
而循环太快。一个肮脏的解决办法是让循环休眠一段时间
但这是一个非常低效的解决方案。因为input()
函数本质上是阻塞的。因此,当while
循环到达msg=input()
行时,整个IOLoop就挂在那里。这意味着在您输入消息之前,Tornado无法运行任何其他操作。如果服务器在此期间发送更多消息,Tornado将无法运行回调
通常,非阻塞应用程序在等待某个事件或事件时应该能够执行其他操作。例如,如果Tornado正在等待您的输入,它应该能够在您没有提供任何输入的情况下运行其他东西。但事实并非如此,因为input()
函数正在阻塞
更好的解决方案是以非阻塞方式接收用户输入。您可以使用sys.stdin
执行此任务
示例(从中修改的代码):
导入系统
类客户端:
...
self.ioloop.add\u处理程序(sys.stdin,self.handle\u输入,ioloop.READ)
@科罗廷将军
def句柄_输入(自身、fd、事件):
msg=fd.readline()
生成self.ws.write_消息(msg)
@科罗廷将军
def运行(自):
#run方法将没有任何内容
#但是你可以把一份打印的声明
#来,把其他东西都拿走
打印(“请输入”)
#对cb_Receive函数的一个小的可选修改
@科罗廷将军
def cb_接收(消息):
打印('msg------>{}'。格式(msg))
#下面的打印语句就在这里
#模拟while循环行为
#打印“请输入”消息的步骤
#请求用户输入,因为
#sys.stdin始终侦听输入
打印(“请输入”)
又是你!你还记得我和我2天前在git中的代码吗?我不会忘记你很久的。再次感谢。实际上,我写的这段代码只是我实际代码的一个简单版本。在我的代码中,输入函数将替换为while循环代码。根据你的回答,它会像上面那样再次阻塞。不可避免地,它运行一些东西并生成消息,以便在每次迭代中将其发送到服务器。在这种情况下,我怎样才能让它像你一样处理呢?@verystrongjoe-Haha,是的,我记得。只需将循环休眠一小段时间,如微秒。或者你可以只做而不产生任何。这也将允许龙卷风运行其他东西。这个方法还可以。最后,我解决了我的问题!谢谢@xyres
import tornado.ioloop
import tornado.web
import tornado.websocket
import os
from tornado import gen
class EchoWebSocket(tornado.websocket.WebSocketHandler):
def open(self):
self.write_message('hello')
@gen.coroutine
def on_message(self, message):
print(message)
yield self.write_message('notification : ', message)
def on_close(self):
print("A client disconnected!!")
if __name__ == "__main__":
app = tornado.web.Application([(r"/", EchoWebSocket)])
app.listen(os.getenv('PORT', 8344))
tornado.ioloop.IOLoop.instance().start()
from tornado.ioloop import IOLoop, PeriodicCallback
from tornado import gen
from tornado.websocket import websocket_connect
@gen.coroutine
def cb_receive(msg):
print('msg----------> {}'.format(msg))
class Client(object):
def __init__(self, url, timeout):
self.url = url
self.timeout = timeout
self.ioloop = IOLoop.instance()
self.ws = None
self.connect()
self.ioloop.start()
@gen.coroutine
def connect(self):
print("trying to connect")
try:
self.ws = yield websocket_connect(self.url,on_message_callback=cb_receive)
except Exception as e:
print("connection error")
else:
print("connected")
self.run()
@gen.coroutine
def run(self):
while True:
print('please input')
msg = input()
yield self.ws.write_message(msg)
print('trying to send msg {}'.format(msg))
if __name__ == "__main__":
client = Client("ws://localhost:8344", 5)