加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Python > 正文

python – websocket.recv()永远不会在另一个事件循环中返回

发布时间:2020-12-20 13:12:29 所属栏目:Python 来源:网络整理
导读:我目前正在开发一个使用websockets和asyncio包的 Python服务器程序. 我得到了一个处理websockets工作的基本脚本(图表A).这个脚本在等待输入时锁定,这不是我想要的. 我想到的解决方案是我可以启动两个异步任务 – 一个处理输入,一个处理输出 – 并在辅助事件
我目前正在开发一个使用websockets和asyncio包的 Python服务器程序.

我得到了一个处理websockets工作的基本脚本(图表A).这个脚本在等待输入时锁定,这不是我想要的.

我想到的解决方案是我可以启动两个异步任务 – 一个处理输入,一个处理输出 – 并在辅助事件循环中启动它们.我不得不对协程进行一些研究,我想出了附件B作为在事件循环中同时运行两件事的概念证明.

现在我坚持的是图表C.当我尝试在带有websockets包的实际场景中使用它时,我发现websocket.recv()永远不会完成(或者协程永远不会停顿 – 我不确定究竟是怎么回事.在展览A中,它工作正常,我已经确定协程肯定至少运行到那时为止.

有任何想法吗?

图表A:

#!/usr/bin/python3

import asyncio
import websockets
import time

# This works great!
async def hello(websocket,path):
    while True:
        # This line waits for input from socket
        name = await websocket.recv()
        print("< {}".format(name))

        # "echo... echo... echo... echo... echo..."
        greeting = ''.join(name + "... " for x in range(5))
        await websocket.send(greeting)
        print("> {}".format(greeting))

        time.sleep(0.1);

start_server = websockets.serve(hello,'',26231)

asyncio.get_event_loop().run_until_complete(start_server)
asyncio.get_event_loop().run_forever()

图表B:

#!/usr/bin/python3
import asyncio
import time

class Thing:
    def __init__(self):
        pass
    async def test(self):
        for x in range(10):
            print("Hello"+str(x))
            await asyncio.sleep(0)
    def run(self):
        # Add the task to the event loop twice
        asyncio.ensure_future(self.test())
        asyncio.ensure_future(self.test())

t = Thing()
t.run()

loop = asyncio.get_event_loop();
loop.run_forever()

图表C:

#!/usr/bin/python3
import asyncio
import websockets
import time

class WebsocketRequest:
    def __init__(self,websocket):
        self.websocket = websocket

    # Works great
    async def handle_oputs(self):
        # This works fine - sends a message
        #  every 10 seconds to the client
        while True:
            print("sending...")
            await self.websocket.send("Hello")
            print("> {}".format("Hello"))
            time.sleep(10)

    # Doesn't work
    async def handle_iputs(self):
        # This stops at the await and never receives
        #  any input from the client :/
        while True:
            try:
                print("receiving...")
                # This is the line that causes sadness
                data = await self.websocket.recv()
                print("< {}".format(data))
            except:
                # This doesn't happen either
                print("Listener is dead")

    async def run(self):

        # This is the part where the coroutine for
        #  a client get split off into two of them
        #  to handle input and output separately.
        loop = asyncio.new_event_loop()

        asyncio.set_event_loop(loop)
        asyncio.ensure_future(self.handle_iputs())
        asyncio.ensure_future(self.handle_oputs())

        loop.run_forever()

class WebsocketServer:
    def __init__(self,address):
        self.ip = address[0]
        self.port = address[1]


    async def hello(self,websocket,path):
        req = WebsocketRequest(websocket)
        await req.run()

    def run(self):
        loop = asyncio.new_event_loop()
        asyncio.set_event_loop(loop)

        start_server = websockets.serve(self.hello,self.ip,self.port)

        asyncio.get_event_loop().run_until_complete(start_server)
        asyncio.get_event_loop().run_forever()

解决方法

也许模块websocket(不像websockets)可以帮助你.

WebsocketApp的使用非常简单:

from websocket import WebSocketApp    

class ExampleClass(object):
    def __init__(self):
        websocket.enableTrace(True)
        self.ws = websocket.WebSocketApp("ws://echo.websocket.org",on_message=on_message,on_error=on_error,on_close=on_close)

    def on_message(ws,msg):
        print "Message Arrived:" + msg

    def on_error(ws,error):
        print error

    def on_close(ws):
        print "Connection Closed"

    def on_open(ws):
       ws.send("Hello!")

下载此模块:https://pypi.python.org/pypi/websocket-client

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读