关闭/关闭Python Websocket
我扩展了关闭/关闭Python Websocket,python,websocket,python-asyncio,Python,Websocket,Python Asyncio,我扩展了websocketecho服务器示例(),以便将其嵌入到Tkinter应用程序中。按下“开始”按钮时,服务器将启动。现在我想在按下“停止”按钮时停止服务器。但是,close()不起作用 server.py: try: import Tkinter as Tk from Tkinter import ttk except ModuleNotFoundError: import tkinter as Tk from tkinter import ttk im
websocket
echo服务器示例(),以便将其嵌入到Tkinter应用程序中。按下“开始”按钮时,服务器将启动。现在我想在按下“停止”按钮时停止服务器。但是,close()
不起作用
server.py
:
try:
import Tkinter as Tk
from Tkinter import ttk
except ModuleNotFoundError:
import tkinter as Tk
from tkinter import ttk
import asyncio
import websockets
class TkEcho():
def __init__(self):
asyncio.get_event_loop().run_until_complete(self.main())
async def main(self):
'''
Add Buttons
'''
root = Tk.Tk()
Tk.Button(root, text='Start', command=lambda: self.start("localhost", 8765)).grid()
Tk.Button(root, text='Stop', command=self.stop).grid()
await self.run_tk(root)
async def run_tk(self, root, interval=0.05):
'''
Add Tk to asyncio
'''
try:
while True:
root.update()
await asyncio.sleep(interval)
except Tk.TclError as e:
if "application has been destroyed" not in e.args[0]:
raise
async def echo(self, websocket, path):
'''
Receives string and sends it back to sender
'''
string = await websocket.recv()
print(f"recv < {string}")
await websocket.send(string)
print(f"send > {string}")
def start(self, host, port):
'''
Starts websocket
'''
start_server = websockets.serve(self.echo, host, port)
asyncio.ensure_future(start_server)
def stop(self):
'''
Stops websocket
'''
None
if __name__ == "__main__":
t = TkEcho()
import asyncio
import websockets
async def send_recv():
uri = "ws://localhost:8765"
async with websockets.connect(uri) as websocket:
string = input("string to send? ")
await websocket.send(string)
print(f"send> {string}")
string = await websocket.recv()
print(f"recv< {string}")
asyncio.get_event_loop().run_until_complete(send_recv())
解决方案:
将TkEcho.\uuuu init\uuuu
替换为:
def __init__(self):
loop = asyncio.get_event_loop()
loop.create_task(self.main())
loop.run_forever()
并按如下方式执行TkEcho.stop
:
def stop(self):
'''
Stops websocket
'''
asyncio.get_event_loop().stop()
要停止程序,只需停止事件循环:
def stop(self):
# terminate the loop
asyncio.get_event_loop().stop()
def __init__(self):
loop = asyncio.get_event_loop()
loop.create_task(self.main())
loop.run_forever() # wait for loop.stop() to terminate us
要使其工作,您需要使用永远运行()
而不是运行直到完成()
来运行事件循环:
def stop(self):
# terminate the loop
asyncio.get_event_loop().stop()
def __init__(self):
loop = asyncio.get_event_loop()
loop.create_task(self.main())
loop.run_forever() # wait for loop.stop() to terminate us
在
stop
的定义中,您是否尝试过类似asyncio.get\u event\u loop().stop()
?这将停止事件循环,并扩展程序的其余部分和服务器。它会导致运行时错误
,并使整个应用程序崩溃。它停止事件循环,但服务器仍在运行:RuntimeError:event loop在将来完成之前已停止。
此错误是由于您如何启动事件循环造成的;您可以通过将\uu init\uu
中的代码替换为loop=asyncio.get\u event\u loop()来修复它;创建_任务(self.main());loop.run_forever()
。谢谢!这就解决了问题。