Trying to connect to Cryptocompare's websocket stream using socketIO from a Python client

+1 vote
from socketIO_client import SocketIO

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

But whenever I try to connect, this is what I get:

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

Kindly help

Aug 6, 2018 in Blockchain by sabby
• 4,050 points
359 views

4 answers to this question.

Your answer

Your name to display (optional):
Privacy: Your email address will only be used for sending these notifications.
+2 votes
Best answer

The reason might be that the the socketio client for python does not work with this API. You might wanna have a working workaround that uses websockets to submit requests to a simple nodejs app that then uses its socketio-client to stream the required data back. 

The socketIO_client library does not seem to support the XHR polling protocol that is used by cryptocompare. You can get it to work by overriding the method recv_packet in the socketIO_client.transports.XHR_PollingTransport class.

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(content, content_index):
    packet_length_string = ''
    while get_byte(content, content_index) != ord(':'):
        byte = get_byte(content, content_index)
        packet_length_string += chr(byte)
        content_index += 1
    content_index += 1
    return content_index, int(packet_length_string)

def new_decode_engineIO_content(content):
    content_index = 0
    content_length = len(content)
    while content_index < content_length:
        try:
            content_index, packet_length = _new_read_packet_length(
                content, content_index)
        except IndexError:
            break
        content_index, packet_text = _read_packet_text(
            content, content_index, 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.content):
        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.')
answered Aug 6, 2018 by Perry
• 16,450 points

selected Aug 6, 2018 by Omkar
0 votes

Try this code:

import json
import pandas as pd
try:
   import thread
except ImportError:
import _thread as thread

import threading
import time
import websocket


class WebSocketClient(threading.Thread):

 def __init__(self):
    self.url = 'ws://localhost:9030/path'
    # self.daemon = True
    self.clist = list()
    threading.Thread.__init__(self)


 def run(self):

    # Running the run_forever() in a seperate thread.
    #websocket.enableTrace(True)
    self.ws = websocket.WebSocketApp(self.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()

 def send(self, data):

    data = self._encode_message(data)
    # Wait till websocket is connected.
    while not self.ws.sock.connected:
        time.sleep(0.25)

    print(f'Sending data... {data}')
    self.ws.send(data)

 def stop(self):
    print(f'Stopping the websocket...')
    self.ws.close()

 def on_message(self, ws, message):
    message = self._decode_message(message)
    print(f'Received data...{message}')
    if message['msg']=='crypto':

        self.clist.append(message['data'])

 def on_error(self, ws, error):
    print(f'Received error...')
    print(error)

 def on_close(self, ws):
    print('Closed the connection...')

 def on_open(self, ws):
    print('Opened the connection...')
    data = {"msg":"open" ,"from":"Rob", "data":"Hello from the client"}
    self.send(data)

 def _encode_message(self,message):

    message = json.dumps(message)
    return message

 def _decode_message(self, message):

    message = json.loads(message)
    return message

 def getclist(self):
    return self.clist


wsCli =  WebSocketClient()
wsCli.daemon = True
wsCli.start()
wsCli.send({"msg":"getcrypto" ,"from":"Client", "data":['0~Coinbase~BTC~USD'],"subs":['0~Coinbase~BTC~USD']})
wsCli.stop()
answered May 7 by Calvin
0 votes

I found this solution on git. It worked for me

var socket = require('socket.io-client')('https://streamer.cryptocompare.com/')
var subscription = ['5~CCCAGG~BTC~USD', '5~CCCAGG~ETH~USD']
socket.emit('SubAdd', {subs: subscription})
socket.on("m", function (message) {
    console.log(message)
})
answered May 7 by Harris
0 votes

You have to specify the transport protocol to make your code. You can do it as follows:

wss://streamer.cryptocompare.com/socket.io/?transport=websocket
answered May 7 by Abhi

Related Questions In Blockchain

+1 vote
3 answers

How to connect peers to a private network using geth?

Follow the below steps to connect peers ...READ MORE

answered Jul 13, 2018 in Blockchain by slayer
• 29,040 points
507 views
0 votes
1 answer

How to connect to already running go ethereum client using mist Ubuntu

Hey, you can solve the issue by using sudo ...READ MORE

answered Sep 18, 2018 in Blockchain by digger
• 27,620 points
37 views
0 votes
2 answers
0 votes
1 answer

Python request module for bitcoin json rpc

This should work: #!/usr/bin/env python import getpass import json import requests ...READ MORE

answered Aug 28, 2018 in Blockchain by digger
• 27,620 points
131 views
0 votes
1 answer

Truffle tests not running after truffle init

This was a bug. They've fixed it. ...READ MORE

answered Sep 11, 2018 in Blockchain by Christine
• 15,790 points
60 views
+2 votes
1 answer
+1 vote
1 answer
0 votes
1 answer

How is a request sent from an app to a smart contract?

Yes, the contract is distributed by every node ...READ MORE

answered Jun 4, 2018 in Blockchain by Perry
• 16,450 points
29 views

© 2018 Brain4ce Education Solutions Pvt. Ltd. All rights Reserved.
"PMP®","PMI®", "PMI-ACP®" and "PMBOK®" are registered marks of the Project Management Institute, Inc. MongoDB®, Mongo and the leaf logo are the registered trademarks of MongoDB, Inc.