When I open the websocket connection from a thread without even retrieving the latest_price_info from the websocket the websocket does not receive any messages, it only receives a first message and does not receive anything else. The following is the code I run:
import threading
import time
from binance_websocket import BinanceWebSocket
lock = threading.Lock()
def manage_websocket(binance_ws):
binance_ws.ws.run_forever()
if __name__ == "__main__":
symbol = "BTCUSDT"
interval = "1m"
binance_ws = BinanceWebSocket(symbol, interval)
websocket_thread = threading.Thread(target=manage_websocket, args=(binance_ws, ))
websocket_thread.start()
print("thread started")
while True:
print("while in icine girdi")
time.sleep(10)
and the following is the websocket code:
import websocket
import json
import time
import threading
class BinanceWebSocket:
def __init__(self, symbol, interval):
self.symbol = symbol
self.interval = interval
self.ws_url = f"wss://stream.binance.com:9443/ws/{self.symbol}@kline_{self.interval}"
self.ws = websocket.WebSocketApp(self.ws_url, on_message=self.on_message, on_error=self.on_error, on_close=self.on_close)
self.ws.on_open = self.on_open
self.latest_price_info = None
self.lock = threading.Lock() # Initialize the lock
def set_latest_price_info(self, price):
with self.lock:
self.latest_price_info = price
def get_latest_price_info(self):
with self.lock:
return self.latest_price_info
def on_message(self, ws, message):
print("The message is: ", message)
data = json.loads(message)
'''
kline = data['k']
close = kline['c']
self.set_latest_price_info(close) # Use the instance method to set the latest price
'''
print("Latest current price updated: ", self.get_latest_price_info())
def on_error(self, ws, error):
print(f"Error: {error}")
def on_close(self, ws, close_status_code, close_msg):
print("WebSocket connection closed")
self.reconnect()
def on_open(self, ws):
print("WebSocket connection opened")
subscription_payload = {
"method": "SUBSCRIBE",
"params": [
f"{self.symbol}@kline_{self.interval}"
],
"id": 1
}
self.ws.send(json.dumps(subscription_payload))
#Binance disconnects websocket connections every 24h, therefore reconnecting when disconnected
def reconnect(self):
while True:
try:
print("Reconnecting...")
time.sleep(5) # Delay before reconnecting
self.ws = websocket.WebSocketApp(self.ws_url, on_message=self.on_message, on_error=self.on_error, on_close=self.on_close)
self.ws.on_open = self.on_open
self.ws.run_forever()
except Exception as e:
print(f"Reconnection failed: {e}")
For example when I open the websocket connection without a thread it is all okay and the self.latest_price_info
attribute of BinanceWebSocket
gets updated as intended if I run the following code, so opening the websocket connection in the main thread:
from binance_websocket import BinanceWebSocket
import time
symbol = "btcusdt"
interval = "1m" # You can adjust the interval here
ws = BinanceWebSocket(symbol, interval)
ws.ws.run_forever()
try:
while True:
lastPriceFrom_ws = ws.latest_price_info
if lastPriceFrom_ws is not None:
print("Latest Current Price:", lastPriceFrom_ws)
time.sleep(1) # Adjust the sleep time if needed
except KeyboardInterrupt:
print("WebSocket connection stopped.")
Initially I was trying to retrieve self.latest_price_info
from the websocket object and I thought there must have been a deadlock situation where the main thread tries to read self.latest_price_info
while the other that runs the websocket connection inside was trying to update it so I started use locks in the websocket class, but later I realized the problem was running the websocket connection in a thread. I even tried joining the other thread to the main thread, but it does not work and while I run the program the websocket just waits and does not receive any messages. It does not return any errors or behaves in any other way. SImply waits on messages but does not receive any.
My main objective is to use the websocket to continuously get price data from Binance exchange. So what I need is to have the websocket continuously updating its attribute latest_price_info
and I want to read the value. Also, if I open the websocket connection it blocks the execution of the main thread that is why I went for a solution by opening the websocket connection in a thread.
The issue was not about running a websocket connection in a thread, but the symbols. Binance websocket subscriptions require non-capitalized symbols such as "btcusdt" instead of "BTCUSDT" this was a detail I missed, when posting the question. SO, both implementation work if non-capitalized symbols are used.