簡體   English   中英

While循環和異步

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM