How to connect to binance websocket service using autobahn with asyncio
Asked Answered
F

2

5

I'm trying to connect to a binance service through:

wss://stream.binance.com:9443/ws/bnbbtc@kline_1m

I know it works because have tried with an online webservice checker and it registers to listen to the server and receives 1m candles without problem.

As I have seen the problem comes when I add the path to the host. If I don't add the path "/ws/bnbbtc@kline_1m" it connects but inmediatelly with error:

WebSocket connection closed: connection was closed uncleanly (WebSocket connection upgrade failed (400 - BadRequest))

This is the code I'm using, mainly extracted from the examples:

from autobahn.asyncio.websocket import WebSocketClientProtocol, WebSocketClientFactory

class MyClientProtocol(WebSocketClientProtocol):

    def onConnect(self, response):
        print("Server connected: {0}".format(response.peer))

    def onOpen(self):
        print("WebSocket connection open.")

    def onMessage(self, payload, isBinary):
        if isBinary:
            print("Binary message received: {0} bytes".format(len(payload)))
        else:
            print("Text message received: {0}".format(payload.decode('utf8')))

    def onClose(self, wasClean, code, reason):
        print("WebSocket connection closed: {0}".format(reason))


if __name__ == '__main__':

    import asyncio

    factory = WebSocketClientFactory()
    factory.protocol = MyClientProtocol

    loop = asyncio.get_event_loop()
    coro = loop.create_connection(factory,"stream.binance.com/ws/bnbbtc@kline_1m", 9443)
    loop.run_until_complete(coro)
    loop.run_forever()
loop.close()

Using this I get the following error from getaddrinfo:

for res in _socket.getaddrinfo(host, port, family, type, proto, flags):
socket.gaierror: [Errno 11003] getaddrinfo failed

I'm really stuck with this, if anyone could help I would really appreciate it.

Fibrosis answered 25/4, 2018 at 15:27 Comment(0)
F
7

Well, After some hours of trying the fix was pretty obvious, I will leave here the code for anyone to check if they need:

factory = WebSocketClientFactory("wss://stream.binance.com:9443/ws/bnbbtc@kline_1m")
factory.protocol = MyClientProtocol

loop = asyncio.get_event_loop()
coro = loop.create_connection(factory,"stream.binance.com", 9443, ssl=True)
loop.run_until_complete(coro)
loop.run_forever()

I was missing the ssl=True part.

Fibrosis answered 25/4, 2018 at 21:44 Comment(1)
are you running this inside a celery worker? how are you handling the possibility that your server becomes unresponsive for the clients while receiving data from the streams, i am assuming all this is running on the main process main threadBunk
P
1

I know, its late, but this will do the trick too and you have to use 4 lines of code:

$ pip install unicorn-binance-websocket-api

from unicorn_binance_websocket_api.unicorn_binance_websocket_api_manager import BinanceWebSocketApiManager
from unicorn_binance_websocket_api_process_streams import BinanceWebSocketApiProcessStreams

binance_websocket_api_manager = BinanceWebSocketApiManager(BinanceWebSocketApiProcessStreams.process_stream_data)
binance_websocket_api_manager.create_stream('kline_1m', 'bnbbtc')

Each websocket you create with 'create_stream' will be created in a separate thread and is written as a coroutine with asyncio.

To process the received data you can use this template: https://github.com/unicorn-data-analysis/unicorn-binance-websocket-api/blob/master/unicorn_binance_websocket_api_process_streams.py

Palmer answered 4/6, 2019 at 14:1 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.