0 votes
1 view
in Blockchain by (4.1k points)

I am trying to connect to Cryptocompare's websocket stream using socketIO from a Python client. This is proving to be challenging. Here is some sample Python code:

from socketIO_client import SocketIO

print "connecting to server"
socketIO = SocketIO('https://streamer.cryptocompare.com/',443, transports=['websocket'])
print "Connected"

 

However, I am not able to connect, whatever I do. In fact, this is the result of that connect

connecting to server
Traceback (most recent call last):
  File "test.py", line 4, in <module>
socketIO = SocketIO('https://streamer.cryptocompare.com/',443, transports=['websocket'])
  File "/usr/local/lib/python2.7/site-packages/socketIO_client/__init__.py", line 353, in __init__
resource, hurry_interval_in_seconds, **kw)
  File "/usr/local/lib/python2.7/site-packages/socketIO_client/__init__.py", line 54, in __init__
self._transport
  File "/usr/local/lib/python2.7/site-packages/socketIO_client/__init__.py", line 62, in _transport
self._engineIO_session = self._get_engineIO_session()
  File "/usr/local/lib/python2.7/site-packages/socketIO_client/__init__.py", line 76, in _get_engineIO_session
transport.recv_packet())
StopIteration

Wrapping the above code in a try-catch and printing the exception yields no extra information. Any help would be greatly appreciated.

1 Answer

0 votes
by (14.4k points)

The reason for the error is the fact that socketIO_client library does not support the XHR polling protocol which happens to be used by cryptocompare. You can make it work by simply overriding the recv_packet method in the socketIO_client.transports.XHR_PollingTransport class. 

Here’s the code that compiles perfectly, 

import logging

import socketIO_client

from socketIO_client.transports import get_response

from socketIO_client.parsers import get_byte, _read_packet_text, parse_packet_text

from requests.exceptions import ConnectionError

# extra function to support XHR1 style protocol

def _new_read_packet_length(contents, content_ind):

    packet_length_string = ''

    while get_byte(contents, content_ind) != ord(':'):

        byte = get_byte(contents, content_ind)

        packet_length_string += chr(byte)

        content_ind += 1

    content_ind += 1

    return content_ind, int(packet_length_string)

def new_decode_engineIO_content(contents):

    content_ind = 0

    content_length = len(contents)

    while content_ind < content_length:

        try:

            content_ind, packet_length = _new_read_packet_length(

                contents, content_ind)

        except IndexError:

            break

        content_ind, packet_text = _read_packet_text(

            contents, content_ind, packet_length)

        engineIO_packet_type, engineIO_packet_data = parse_packet_text(

            packet_text)

        yield engineIO_packet_type, engineIO_packet_data

def new_recv_packet(self):

    params = dict(self._params)

    params['t'] = self._get_timestamp()

    response = get_response(

        self.http_session.get,

        self._http_url,

        params=params,

        **self._kw_get)

    for engineIO_packet in new_decode_engineIO_content(response.contents):

        engineIO_packet_type, engineIO_packet_data = engineIO_packet

        yield engineIO_packet_type, engineIO_packet_data

setattr(socketIO_client.transports.XHR_PollingTransport, 'recv_packet', new_recv_packet)

logging.basicConfig(level=logging.DEBUG)

try:

    socket = socketIO_client.SocketIO('https://streamer.cryptocompare.com')

    socket.emit('SubAdd', { 'subs': ['0~Kraken~BTC~USD'] });

    socket.wait()

except ConnectionError:

    print('The server is down. Try again later.')

Welcome to Intellipaat Community. Get your technical queries answered by top developers !


Categories

...