Reputation: 542
I'm trying to get a websocket connection working in a class, because I need to access the variable self.close
outside of the class.
The problem is that the connection is not established and I also can't access the variable inside on_message
How can I get it to work?
import websocket
import json
class WS:
def __init__(self):
self.socket = 'wss://ftx.com/ws/'
def stream(self):
self.ws = websocket.WebSocketApp(self.socket,
on_message=self.on_message,
on_error=self.on_error,
on_close=self.on_close)
self.ws.run_forever()
def on_open(self):
print('connected')
data = {'op': 'subscribe', 'channel': 'ticker', 'market': 'ETH-PERP'}
self.ws.send(json.dumps(data))
def on_close(ws):
print('disconnected')
def on_message(self,message):
json_msg = json.loads(message)
self.close = json_msg['data']['last']
def get_data_out(self):
return self.close
def on_error(ws,error):
print(error)
Upvotes: 1
Views: 3409
Reputation: 142794
I tried to run your code
WS().stream()
but it doesn't work for me (even if I add missing on_open=self.on_open
)
I found even ftx documentation and its example with also use module websocket
but I didn't test it.
But if I use different module websockets (with char s
) instead of websocket
(without char s
) then I can subscribe channel and get values.
Minimal working example
import asyncio
import websockets
import json
async def handler():
async with websockets.connect('wss://ftx.com/ws/') as ws:
# subscribe
data = {'op': 'subscribe', 'channel': 'ticker', 'market': 'ETH-PERP'}
await ws.send(json.dumps(data))
# get all messages (not only with `update`)
async for message in ws:
print(message)
# --- main ---
asyncio.get_event_loop().run_until_complete(handler())
To get only last
value it needs to filter messages:
async for message in ws:
data = json.loads(message)
if data['type'] == 'update':
print(data['data']['last'])
But it still need to write more code if you want to use it as class.
BTW:
It seems websocket
(without char s
) is very old module and last updated was in 2010 and websockets
(with char s
) was updated in 2021 (few weeks/months ago).
https://pypi.org/project/websocket/
https://pypi.org/project/websockets/
EDIT:
In other question I found command which show more information about connection:
websocket.enableTrace(True)
and this shows errors because functions are executed with more values then you defined.
They have to get websocket
as first argument (after self
)
You have:
def on_open (self):
def on_close (ws):
def on_message(self, message):
def on_error (ws, error):
but it has to be
def on_open (self, ws):
def on_close (self, ws):
def on_message(self, ws, message):
def on_error (self, ws, error):
You also forgot on_open=self.on_open
Full working code
import websocket
import json
class WS:
def __init__(self):
self.socket = 'wss://ftx.com/ws/'
self.close = None # default value at start
def stream(self):
self.ws = websocket.WebSocketApp(
self.socket,
on_message=self.on_message,
on_error=self.on_error,
on_close=self.on_close,
on_open=self.on_open
)
print('run forever')
self.ws.run_forever()
def on_open(self, ws):
print('on_open:', ws)
data = {'op': 'subscribe', 'channel': 'ticker', 'market': 'ETH-PERP'}
self.ws.send(json.dumps(data))
def on_close(self, ws):
print('on_close:', ws)
def on_message(self, ws, message):
print('on_message:', ws, message)
data = json.loads(message)
if data['type'] == 'update':
self.close = data['data']['last']
def get_data_out(self):
return self.close
def on_error(self, ws, error):
print('on_error:', ws, error)
# --- main ---
websocket.enableTrace(True) # if you want to see more information
# but code works also without this line
WS().stream()
Upvotes: 2