slazarov / python-bittrex-websocket

Python websocket for Bittrex (non async).
http://python-bittrex-websocket-docs.readthedocs.io/en/latest/index.html
MIT License
103 stars 38 forks source link

How to get multiple websockets to work at once? #60

Closed hamkline closed 6 years ago

hamkline commented 6 years ago

I finally got the websocket to work after checking the Getting real-time non-stop ticker updates #23 post, but now I have another problem. I need to have 1 websocket working on one function, and another on a different one with the first function calling the second at some point, like so:

def main():
    class MySocket(BittrexSocket):
        def __init__(self, url=None):
            super(MySocket, self).__init__(url)
            self.ticker_updates_container = {}        
            self.balances = {} #need this to work the same as ticker_updates_container

        def on_public(self, msg):           
            self.ticker_updates_container = msg

        def function1(self):   
            while True:                                 
                for i in self.ticker_updates_container['D']:    
                    dostuff
                    self.function2()
        def function2(self):
            while True:
                for i in balances:

    # Create the socket instance
    ws = MySocket()

    # Enable logging
    ws.enable_log()

    # Subscribe to ticker information   
    ws.subscribe_to_summary_deltas()  
    ws.authenticate(key, secret) #This is what I need for function2, on a while True loop
    time.sleep(10)
    ws.function1()

    while True:
        pass

if __name__ == "__main__":
    main()

But I don't know how to. In the example I use balances, it's the one on authenticate method, I think a better way to put it is that I don't understand how the msg get to on_public, and because of that I can't think of a way to add another websocket with something like

def on_balance(self, msg):    
    self.balance = msg

I tried both def on_private and def _on_private but it doesn't work. I know this should be my problem but maybe a lot of people could use it like the other info post, sorry to bother you.

slazarov commented 6 years ago

Hi, put the on_private channel in the MySocket class, e.g below the on_public. They function in the same way. When you subscribe to summary deltas and authenticate, both channels will start streaming. In the case of on_private when something happens on your balance. You should put the function call in the while true loop. Hope that clarifies it, can’t post any code right now because I’m on my phone.

hamkline commented 6 years ago

So I actually got the idea right by using on_private, what I didn't notice is that I was receiving only {} when printing because there was no change to my balances?

There is something else I'd like to ask: Is there a way to use two on_public channels at the same time? Let's say subscribe_to_exchange_deltas and subscribe_to_summary_deltas

slazarov commented 6 years ago

There is no problem. Subscriptions are done in a separate thread, so when you subscribe the on channel will receive messages from both subs.

hamkline commented 6 years ago

Should I use an if to check which msg is which then?

slazarov commented 6 years ago

Yes, because they have different output formats. The library is just a client, what you do depends on your preferences. E.g you can create a new channel and redirect a specific subscription from the on_public channel to it.

slazarov commented 6 years ago

Something like that:

def main():
    class MySocket(BittrexSocket):
        def __init__(self, url=None):
            super(MySocket, self).__init__(url)
            self.ticker_updates_container = {}        
            self.balances = {} #need this to work the same as ticker_updates_container

        def on_public(self, msg):           
            # Get messages from summary and exchange deltas
            # Apply if/else to differentiate them
            self.ticker_updates_container = msg

       def on_private(self,msg):
             # Get private data
             print(msg)

        def function1(self):   
            while True:                                 
                for i in self.ticker_updates_container['D']:    
                    dostuff
                    self.function2()
        def function2(self):
            while True:
                for i in balances:

    # Create the socket instance
    ws = MySocket()

    # Enable logging
    ws.enable_log()

    # Subscribe to ticker information 
    # DON'T LOOP SUBSCRIPTION METHODS, YOU WILL GET THROTTLED AND BANNED
    ws.subscribe_to_summary_deltas()  
    ws.subscribe_to_exchange_deltas()  
    ws.authenticate(key, secret) #This is what I need for function2, on a while True loop

    while True:
        # Apply logic
        ws.function(1)
        # If the function is idle, use time.sleep(N)

if __name__ == "__main__":
    main()
hamkline commented 6 years ago

This is very informative, thank you!