简体   繁体   中英

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. 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.

I'm using this websocket-client lib ( https://github.com/websocket-client/websocket-client ) and using a "Long-lived connection" example from that page.

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.

When I use the SubscibeData method I get the expected response. So the websocket part works fine.

The on_message method saves the response in self.sub but that isn't returned anywhere.

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...

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.

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. 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.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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