Reputation: 2064
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...
Upvotes: 4
Views: 3167
Reputation: 2064
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.
Upvotes: 1