Recently I’m working on a Django project in which I need to get the price of some cryptocurrencies like BTC, ETH, and …
So I used BinanceSocketManager in a class that uses multiprocessing.
It works fine on my local machine but when I started to deploy it to Centos 7 server, faced some problems. The problem is that the BinanceSocketManager doesn’t call the trade_prices function to pass the received message to it and get the prices.
(I’m using Nginx webserver with Python version 3.6.8 and pip and gunicorn and daphne)
Here is my code:
import multiprocessing
from binance.client import Client
from binance.websockets import BinanceSocketManager
global PRICES
PRICES = {}
PUBLIC = 'My-Public-key'
SECRET = 'My-Private-key'
# This method works on development mode but doesn't work on deploy mode!
def trade_prices(msg):
# I can see these print statements on my local machine terminal but not on the server!
print("msg : ", msg)
if msg['s'] == 'BTCUSDT':
PRICES['BTCUSDT'] = [msg['c'], msg['P']]
print("PRICES : ", PRICES)
class Process(multiprocessing.Process):
__instance = None
@staticmethod
def getInstance():
if Process.__instance is None:
Process()
return Process.__instance
def __init__(self):
super().__init__()
if Process.__instance is not None:
# raise Exception("This class is a singleton class!")
pass
else:
Process.__instance = self
self.start()
def run(self):
client = Client(api_key=PUBLIC, api_secret=SECRET)
bsm = BinanceSocketManager(client)
# The line below works correctly on development mode and calls the trade_prices function and passes the msg to it
# But it doesn't work correctly on Centos 7 server when I deploy it.
conn_key = bsm.start_symbol_ticker_socket('BTCUSDT', trade_prices)
print("conn_key : ", conn_key)
bsm.start()
Process().getInstance()
what did I do wrong?
Is there any additional Nginx config in /etc/nginx/nginx.conf for Binance websocket that I forgot to use?
Best regards.
The problem resides in the way you use multiprocessing. The way you call binance wss has no problem. Please dig into how to start additional processes using multiprocessing in a python-tech forum
Thanks for your comment @MJW . I (had to) implement the multiprocessing in this way.
let me explain a little more about my project so it can be clearer:
I want to show the cryptocurrencies’ price and last24 price change to all of my users that visit my website. I made two WebSockets. One WebSocket connects users to my Django backend, then when the first user connects to the backend, One and just one object of multiprocessing class creates forever (singleton design pattern), so it doesn’t create any more instance of the class when more users go to the website.
And this multiprocessing object will be connected to Binance WebSocket, get the data from it, and store it in Redis cache.
Then the first WebSocket gets the data from the cache every 5 seconds and sends it through my Django WebSocket to the users.
In other words, the very one WebSocket that connects to Binance, get the data and place it in the cache, and the WebSockets that connects to users, get the data from the cache and serve it for users.
So There may be millions of connections to the first Websocket that connects users to my Django backend, but there should be just one connection to Binance WebSocket not millions of connections.
Maybe there were better ways to do this job, but at that time, this way of implementing comes to my mind.
Any suggestion for better ways of implementing?
Your design is good. But I don’t see how it’s helping me understand your current problem. As per your code, it doesn’t even work to instantiate an object of this Process class
In fact, I minimized my code to show the core code.
In the line Process().getInstance(), the getInstance() calls and it that function The Process class just calls, so that the __init__ method of the Process class runs. And in there, I defined that if there wasn’t any instance of the class, so start it:
if Process.__instance is not None:
# raise Exception("This class is a singleton class!")
pass
else:
Process.__instance = self
self.start()
The run function of the Process class works correctly (I see the print statement in the daphne console in the server). But the line below :
conn_key = bsm.start_symbol_ticker_socket(‘BTCUSDT’, trade_prices)
doesn’t work on the server!
Of course, I’m not sure 100% that this way is correct