2016-02-20 59 views
1

我需要一個長時間運行的websocket客戶端接收來自websocket服務器的推送消息,我需要監視客戶端的連接狀態:如果連接斷開,我需要找出答案。Python異步websocket客戶端與異步計時器

我的方法是週期性地記錄一個常量字符串,並且如果沒有檢測到日誌消息就會觸發警報。

我的想法:1)有一個websocket客戶端,可以響應不規則的傳入消息。 2)同時有循環,當websocket客戶端拋出一個ConnectionClosed的豁免時停止記錄消息。

我對新的3.5異步語法很感興趣。 This websocket實現特別基於asyncio。文檔中的client看起來完全像我需要的。

但是,我不知道如何添加第二個協程,我的日誌語句在websocket連接拋出ConnectionClosed時以某種方式停止。

以下是啓動對話的內容,但不起作用,因爲alive方法會阻止事件循環。我正在尋找的是一個同時運行這兩種方法的優雅解決方案。

#!/usr/bin/env python 

import asyncio 
import logging 

import websockets 

logger = logging.getLogger(__name__) 

is_alive = True 


async def alive(): 
    while is_alive: 
     logger.info('alive') 
     await asyncio.sleep(300) 


async def async_processing(): 
    async with websockets.connect('ws://localhost:8765') as websocket: 
     while True: 
      try: 
       message = await websocket.recv() 
       print(message) 

      except websockets.exceptions.ConnectionClosed: 
       print('ConnectionClosed') 
       is_alive = False 
       break 


asyncio.get_event_loop().run_until_complete(alive()) 
asyncio.get_event_loop().run_until_complete(async_processing()) 

回答

4

其實run_until_complete阻塞在這裏,因爲它一直等待,直到alive完成。與asyncio.ensure_future

  1. 時間表協同程序(立即運行,無需等待結果),每區選出的任務:

    你可以用2步解決它。

  2. 等待任務,拿完與asyncio.wait

的代碼,如:

tasks = [ 
    asyncio.ensure_future(alive()), 
    asyncio.ensure_future(async_processing()) 
] 
asyncio.get_event_loop().run_until_complete(asyncio.wait(tasks)) 

由於@Vincent提到wait接受任務,所以ensure_future不用:

asyncio.get_event_loop().run_until_complete(asyncio.wait([ 
    alive(), 
    async_processing() 
])) 
+0

工程就像一個魅力。非常感謝。 –

+1

你可以傳遞一個協程列表給'asyncio.wait',在你的例子中不需要使用'asyncio.ensure_future'。 – Vincent