【问题标题】:Accessing incoming messages with a Python websocket client使用 Python websocket 客户端访问传入消息
【发布时间】:2020-04-30 21:16:55
【问题描述】:

我正在尝试通过 websocket-client 模块接收消息,并能够将收到的消息用于其他目的(例如,根据传入的消息执行买/卖订单)。

这是我目前所拥有的:

import websocket
import time
import json

def on_message(ws, message):
    try:
        current_price = json.loads(message)
        print(current_price["price"])       # data type is dict.. only showing values for the key 'price'

    except:
        print("Please wait..")
        time.sleep(1)          

def on_error(ws, error):
    print(error)


def on_close(ws):
    print("### closed ###")


def on_open(ws):
    sub_params = {'type': 'subscribe', 'product_ids': ['BTC-USD'], 'channels': ['ticker']}
    ws.send(json.dumps(sub_params))

if __name__ == "__main__":
    websocket.enableTrace(False)
    ws = websocket.WebSocketApp("wss://ws-feed.pro.coinbase.com/",
                              on_open = on_open,
                              on_message = on_message,
                              on_error = on_error,
                              on_close = on_close)

    ws.run_forever()

运行此代码将打印当前比特币价格 (current_price),因为它们通过其 websocket 提要进入。

我接下来要做的是能够在 websocket 函数之外访问该变量current_price,我在这里遇到了困难。写入ws.run_forever() 之外的任何内容都将被忽略,因为 websocket 事件循环永远不会结束。

所以我尝试使用“线程”模块在单独的线程上运行 websocket:

    import websocket
  import json
  import threading

  current_price = 0

  def on_message(ws, message):

      global current_price
      current_price = message

  def on_error(ws, error):
      print(error)

  def on_close(ws):
      print("### closed ###")


  def on_open(ws):
      sub_params = {'type': 'subscribe', 'product_ids': ['BTC-USD'], 'channels': ['ticker']}
      ws.send(json.dumps(sub_params))

  if __name__ == "__main__":
      websocket.enableTrace(False)
      ws = websocket.WebSocketApp("wss://ws-feed.pro.coinbase.com/",
                                on_open = on_open,
                                on_message = on_message,
                                on_error = on_error,
                                on_close = on_close)

      ws_thread = threading.Thread(target = ws.run_forever)
      ws_thread.start()
      print(current_price)

这将返回0。我可以做些什么来完成这项工作?

【问题讨论】:

    标签: python python-3.x websocket


    【解决方案1】:

    不确定这是否是最合适的答案,但找到了一种方法。

    import queue
    .
    .
    .
    .
    
        def on_message(ws, message):
                current_price = message
                q.put(current_price)
        .
        .
        .
    
        ws_thread.start()
    
        while True:
            print(q.get())
    

    【讨论】:

    • 队列是一种非常好的线程间通信方式。您之前方法的问题是 websocket 在打印 current_price 之前没有机会发送和接收消息(请参阅en.wikipedia.org/wiki/Race_condition)。 q.get() 方法调用会一直等待,直到队列中有项才返回。
    猜你喜欢
    • 2018-09-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-14
    • 1970-01-01
    • 2021-07-06
    • 2012-02-11
    相关资源
    最近更新 更多