关闭/关闭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()
。谢谢!这就解决了问题。