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函数从队列中提取并执行这些任务。如果有效,将发布答案!