[英]While loop and asyncio
再會!
我正在嘗試編寫 WebSocket 連接器並使用 asyncio。 我對異步方法不太熟悉,因此會發生不正確的行為。 下面是代碼的簡化版本。
import pandas as pd
import json
import websockets
import asyncio
import time
class BinanceQuotesWS:
def __init__(self,client,pair):
self.quotes = pd.DataFrame(columns=['Timestamp','Price'])
self.pair = pair
self.socket='wss://fstream.binance.com/ws'
self.websocket = None
self.loop = None
self.result = None
def get_quotes(self):
return self.quotes
def start(self):
self.loop = asyncio.get_event_loop()
self.result = self.loop.create_task(self.connect())
async def connect(self):
self.websocket = await websockets.connect(self.socket)
await self.subscribe_quotes()
async def subscribe_quotes(self):
subscribe_message = {
"method": "SUBSCRIBE",
"params":
[
self.pair.lower()+"@trade"
],
"id": 1
}
subscribe_message = json.dumps(subscribe_message)
await self.websocket.send(subscribe_message)
async for msg in self.websocket:
msg = json.loads(msg)
if('p' in msg):
self.quotes.loc[0] = [msg['E'],float(msg['p'])]
temp_ws = BinanceQuotesWS(client,'BTCUSDT')
temp_ws.start()
當我在 Jupyter 中對其進行測試並手動執行帶有temp_ws.get_quotes()
的單元格時,每次都會返回帶有新引號的正確 dataframe 。
雖然在我的程序中我需要有一些無限循環並且出現錯誤。
while(True):
quotes = temp_ws.get_quotes()
print(quotes)
time.sleep(3)
quotes
DF 始終為空,但我無法弄清楚原因(可能是因為 while 循環被阻塞)。 如果有人可以幫助解決這個問題,我會很高興(如果在異步請求方面可以改進代碼中的任何其他內容,請給出一些提示)。 謝謝你。
您可以使用asyncio.sleep
創建async
function
async def display(self):
while True:
await asyncio.sleep(3)
quotes = self.get_quotes()
print('time:', quotes['Timestamp'][0], 'price:', quotes['Price'][0])
並將其添加到循環
self.result2 = self.loop.create_task(self.display())
然后你可以在同一個循環中運行所有
temp_ws.loop.run_forever()
如果您不使用run_forever()
那么它不會運行connect()
-並且您不會在標准循環中獲得值。 但是這個循環必須一直運行,它不能與正常循環同時運行(也必須一直運行)。 其中一個循環必須在單獨的線程中運行。
但是await
(whit asyncio.sleep
) 解決了問題。 當它在while True
休眠時,它會進入其他功能並且它可以運行其他代碼 - 后來一些其他代碼使用await
然后它可以 go 回到while True
。
也許在Jupyter
中它可以與run_forever()
一起使用,因為它們添加了許多額外的功能以使生活更輕松(並且在Jupyter
中使用的元素可能需要此循環才能正常工作),但在普通程序中,您必須手動使用run_forever()
。
最小的工作代碼:
import pandas as pd
import json
import websockets
import asyncio
import time
class BinanceQuotesWS:
def __init__(self,client,pair):
self.quotes = pd.DataFrame(columns=['Timestamp','Price'])
self.pair = pair
self.socket='wss://fstream.binance.com/ws'
self.websocket = None
self.loop = None
self.result = None
def get_quotes(self):
return self.quotes
def start(self):
self.loop = asyncio.get_event_loop()
self.result = self.loop.create_task(self.connect())
self.result2 = self.loop.create_task(self.display())
async def connect(self):
self.websocket = await websockets.connect(self.socket)
await self.subscribe_quotes()
async def subscribe_quotes(self):
subscribe_message = {
"method": "SUBSCRIBE",
"params": [
self.pair.lower()+"@trade"
],
"id": 1
}
subscribe_message = json.dumps(subscribe_message)
await self.websocket.send(subscribe_message)
async for msg in self.websocket:
msg = json.loads(msg)
if('p' in msg):
self.quotes.loc[0] = [msg['E'],float(msg['p'])]
#print(self.quotes)
async def display(self):
while True:
await asyncio.sleep(3)
quotes = self.get_quotes()
print('time:', quotes['Timestamp'][0], 'price:', quotes['Price'][0])
client = ''
temp_ws = BinanceQuotesWS(client,'BTCUSDT')
temp_ws.start()
temp_ws.loop.run_forever()
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.