我目前正在開發一個服務器程序在Python中使用websockets和asyncio包。websocket.recv()永遠不會返回另一個事件循環內
我得到了一個基本的腳本處理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()
嘗試使用帶有on_message事件的WebSocketApp事件 –
我非常喜歡使用類似的東西 - 事件驅動會更容易處理。我找不到在服務器中使用的WebSocketApp的任何示例;它只是爲了客戶嗎? –
埃裏克,我使用python龍捲風websocket。你可以在這裏找到一個教程http://www.tornadoweb.org/en/stable/websocket.html ...給出了很好的例子。檢查出。是的,on_message將解決這個問題,正如Gabriel已經提到的那樣。 – SanD