Python 如何从tkinter的线程中通过websocket发送消息?
我有一个正在运行的服务器脚本:Python 如何从tkinter的线程中通过websocket发送消息?,python,asynchronous,tkinter,websocket,coroutine,Python,Asynchronous,Tkinter,Websocket,Coroutine,我有一个正在运行的服务器脚本: async def give_time(websocket,path): while True: await websocket.send(str(datetime.datetime.now())) await asyncio.sleep(3) start_server = websockets.serve(give_time, '192.168.1.32', 8765) asyncio.get_event_loop()
async def give_time(websocket,path):
while True:
await websocket.send(str(datetime.datetime.now()))
await asyncio.sleep(3)
start_server = websockets.serve(give_time, '192.168.1.32', 8765)
asyncio.get_event_loop().run_until_complete(start_server)
asyncio.get_event_loop().run_forever()
工作正常,每3秒发送一次当前时间
我可以从运行以下代码的客户端接收该字符串:
async def hello(): #takes whatever text comes through the websocket and displays it in the socket_text label.
async with websockets.connect('ws://wilsons.lan:8765') as ws:
while True:
text = await ws.recv()
logger.info('message received through websocket:{}'.format(text))
socket_text.configure(text=text) #socket_text is a tkinter object
loop = asyncio.new_event_loop()
def socketstuff():
asyncio.set_event_loop(loop)
asyncio.get_event_loop().run_until_complete(hello())
t = threading.Thread(target=socketstuff,daemon=True)
它在线程中运行,这样我就可以在主线程中运行tkinter.mainloop
。这是我第一次使用线程
,所以我可能弄错了,但目前它似乎可以工作
我需要做的是,能够根据tkinter事件在websocket上发送消息——目前只需单击文本框旁边的按钮,但最终会发送更复杂的消息。点击部分工作正常
我在发送信息方面遇到了很多麻烦。我尝试了很多不同的方法,有无async
和wait
,尽管这可能只是恐慌
主要问题似乎是我无法从hello()
函数外部访问ws
。这是有道理的,因为我将与
上下文管理器一起使用。但是,如果我只使用ws=websockets.connect('ws://host')
,那么我会得到一个websockets.py35.client.connect对象
,我尝试使用send
(或者实际上是recv
)方法,我会得到一个对象没有属性“send”
错误
我希望这是足够的信息-将愉快地张贴任何其他要求 事实证明,解决这个问题的最佳方法不是使用线程 帮我解决了。它表明您可以在协同程序中运行tkinter Main循环的一次迭代:
async def do_gui(root,interval=0.05):
while True:
root.update()
await asyncio.sleep(interval)
但是,获取tkinter事件以生成websocket消息的最佳方法是使用
asyncio.queue
。使用put\u nowait()
使tkinter回调向队列添加一个项目,并使用do\u gui
同时运行一个协同程序,该程序使用wait queue.get()
从队列获取消息对我来说很有效。再考虑一下这个问题,我似乎在这里写错了。线程不是问题所在-我已将其更改为tkinter.mainloop()
在asyncio主循环中运行,因此现在不需要线程。但是,在上下文管理器外部访问websocket的问题仍然存在。我现在要尝试的是对tkinter事件使用asyncio.queue
,将websocket消息任务添加到,并使用asyncio函数从队列中提取并执行这些任务。如果有效,将发布答案!