简体   繁体   English

如何将从 websocket 接收到的 on_message 数据返回到类外部? 使用 python websocket-client

[英]How to return on_message data received from websocket to outside of the class? Using python websocket-client

I'm trying to make my code get me some data from a Websocket connection and then use the data from the WS response.我试图让我的代码从 Websocket 连接中获取一些数据,然后使用来自 WS 响应的数据。 The thing is, I don't know how to make the code wait for the WS answer and then 'send' the data to outside the WS Class.问题是,我不知道如何让代码等待 WS 回答,然后将数据“发送”到 WS 类之外。

I'm using this websocket-client lib ( https://github.com/websocket-client/websocket-client ) and using a "Long-lived connection" example from that page.我正在使用这个 websocket-client lib ( https://github.com/websocket-client/websocket-client ) 并使用该页面中的“长期连接”示例。

import websocket
import _thread as thread
import time, json

class Frame:
  def __init__(self):
    self.m = 0 
    self.i = 0 
    self.n = ""
    self.o = ""

class MyWS():
    def __init__(self):
        self.wsadd = 'ws://websocket.org/' #Example 
        self.frame = Frame()

        self.openWS()

    def on_message(self, message):
        msg = json.loads(message)
        print(msg)
        if msg["n"] == 'SubscribeData':
            self.sub = json.loads(msg['o'])
            return self.sub #It doesn't seem to do anything

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

    def on_close(self):
        print("WS closed")

    def on_open(self):
        def run(*args):
            print('WS Open')
            #self.Authenticate() #Commented because haven't code it yet
            #self.sendWS()
            thread.start_new_thread(run, ())

    def openWS(self):
        websocket.enableTrace(True)
        self.ws = websocket.WebSocketApp(self.wsadd, on_message = self.on_message, on_open = self.on_open, on_error = self.on_error, on_close = self.on_close)
        self.wst = threading.Thread(target=lambda: self.ws.run_forever())
        self.wst.daemon = True
        self.wst.start()

    def sendWS(self):
        self.ws.send(json.dumps(self.frame.__dict__))


    def SubscribeData(self):
        self.frame.m = 0
        self.frame.i = int(time.time())
        self.frame.n = 'SubscribeData'
        payload = {
            "OMSId": 1,
            "InstrumentId": 1,
            }
        self.frame.o = json.dumps(payload)
        self.sendWS(self.frame)
        #return #Should return something here?

obj = MyWS() #When the obj is instantiated the WS Connection is opened.

result = obj.SubscribeData() #This sends a request for subscribing to the datafeed. It get's an answer but isn't saved in the variable. (because the method doesn't really return anything)

print(result) #prints None

When I instantiate the MyWS class the WS connection is openend.当我实例化MyWS类时,WS 连接是开放的。

When I use the SubscibeData method I get the expected response.当我使用SubscibeData方法时,我得到了预期的响应。 So the websocket part works fine.所以 websocket 部分工作正常。

The on_message method saves the response in self.sub but that isn't returned anywhere. on_message方法将响应保存在self.sub但不会在任何地方返回。

What I really need is a way for the data received to be sent 'outside' the class so the 'outside code' not only waits for the data to be received, but also can manipulate it我真正需要的是一种将接收到的数据发送到“外部”类的方法,因此“外部代码”不仅等待接收数据,还可以对其进行操作

I'm pretty new to websockets, just so you know...我对 websockets 很陌生,所以你知道......

To answer @HJA24 and who else might stumble uppon this question, I didn't really found a (good) solution to this, but made a workaround.要回答@HJA24 以及还有谁可能会偶然发现这个问题,我并没有真正找到一个(好的)解决方案,但做了一个解决方法。

Since the on_message method saved the return in self.sub I created another method that returned the value for self.sub , that way I could access the WS response.由于on_message方法将返回值保存在self.sub我创建了另一个返回self.sub值的self.sub ,这样我就可以访问 WS 响应。 If you decide to go with this method you have to account for the fact that the WS may take longer to answer you than the time it takes for you to call the method that returns the value.如果您决定采用此方法,则必须考虑到这样一个事实,即 WS 回答您的时间可能比您调用返回值的方法所需的时间更长。

Something like this:像这样的东西:

import websocket
import ...

class MyWS():
    def __init__(self):
        self.wsadd = 'ws://websocket.org/' #Example 
        self.frame = Frame()
        self.openWS()

    def on_message(self, message):
        msg = json.loads(message)
        if msg["n"] == 'SubscribeData':
            self.sub = json.loads(msg['o'])

    def get_subscribe_data(self):
        return self.sub

    def on_error(self, error):
        ...

obj = MyWS() #When the obj is instantiated the WS Connection is opened.

obj.SubscribeData()
result = obj.get_subscribe_data()
print(result) #prints the data on self.sub

I'm not accepting my own answer because surely there is a better way to do this, so if you are reading this and have an idea, feel free to share.我不接受我自己的答案,因为肯定有更好的方法来做到这一点,所以如果您正在阅读本文并有想法,请随时分享。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM