var socket = require('socket.io-client')('https://streamer.cryptocompare.com/')
var socketon = false
var WebSocketServer = require('ws').Server , wss = new WebSocketServer({port: 9030});
wss.on('connection', function(ws) {
ws.on('message', function(message) {
\t \t \t msg = decode_message(message);
console.log('received: %s', message);
console.log('test: %s', msg['msg']);
\t \t \t \t \t \t \t switch(msg['msg']) {
\t \t \t \t \t \t \t \t case 'open':
message_type = 'open';
\t \t \t \t \t \t \t \t \t
\t
\t \t \t \t \t \t \t \t \t // do something with chat data. i.e.:
\t \t \t \t \t \t \t \t \t console.log("open from " + msg['from'] +
\t \t \t \t \t \t \t \t \t \t ": " + msg['data']);
\t \t \t \t \t \t \t \t \t
outmessage = 'welcome from server ' + msg['from'];
\t \t \t \t \t \t \t \t \t ws.send(encode_message(outmessage, message_type = 'open'));
\t \t \t \t \t \t \t \t \t break
\t \t \t \t \t \t \t \t case 'getcrypto':
\t \t \t \t \t \t \t \t \t message_type = "crypto"
\t \t \t \t \t \t \t \t \t // do something with chat data. i.e.:
\t \t \t \t \t \t \t \t \t console.log("'getcrypto': object" + msg['data']);
socket.emit('SubAdd', { subs: msg.subs });
if (!socketon) {
socket.on("m", function (message) {
var messageType = message.substring(0, message.indexOf("~"));
var res = {};
switch (messageType) {
case CCC.STATIC.TYPE.TRADE:
res = CCC.TRADE.unpack(message);
break;
case CCC.STATIC.TYPE.CURRENT:
res = CCC.CURRENT.unpack(message);
break;
case CCC.STATIC.TYPE.CURRENTAGG:
res = CCC.CURRENT.unpack(message);
// updateQuote(res);
break;
case CCC.STATIC.TYPE.ORDERBOOK:
res = CCC.ORDER.unpack(message);
break;
case CCC.STATIC.TYPE.FULLORDERBOOK:
res = CCC.ORDER.unpack(message);
break;
}
console.log(message);
console.log(res);
ws.send(encode_message(res, message_type = "crypto"));
})
}
socketon = true;
\t \t \t \t \t \t \t \t \t break
\t \t \t \t \t \t \t \t case 'canccrypto':
\t \t \t \t \t \t \t \t \t // do something with chat data. i.e.:
\t \t \t \t \t \t \t \t \t message_type = "crypto"
\t \t \t \t \t \t \t \t \t console.log(msg['msg'] +":" + msg['data']);
\t \t \t \t \t \t \t \t \t socket.emit('SubRemove', { subs: msg.subs });
\t \t \t \t \t \t \t \t \t break
\t \t \t \t \t \t \t \t case 'other':
\t \t \t \t \t \t \t \t \t // do something with chat data. i.e.:
\t \t \t \t \t \t \t \t \t
\t \t \t \t \t \t \t \t \t console.log("open from " + msg['from'] +
\t \t \t \t \t \t \t \t \t \t ": " + msg['data']);
\t \t \t \t \t \t \t \t \t outmessage = 'other from server ' + msg['from']
\t \t \t \t \t \t \t \t \t ws.send(encode_message(outmessage, message_type = "other"));
\t \t \t \t \t \t \t \t \t break
\t \t \t \t \t \t \t \t // ... and so on
\t \t \t \t \t \t \t }
});
});
function decode_message(message) {
\t msg = JSON.parse(message);
\t return msg;
}
function encode_message(message, messsage_type) {
\t if (message_type == "crypto") {
\t \t var msg_crypto = { 'msg': 'crypto', 'data': message };
\t \t msg = JSON.stringify(msg_crypto);
\t }
\t else {
\t \t var msg_other = { 'msg': 'other', 'data': message };
\t \t msg = JSON.stringify(msg_other);
\t }
\t return msg;
}
var CCC = CCC || {};
CCC.STATIC = CCC.STATIC || {};
CCC.STATIC.TYPE = {
\t 'TRADE': '0'
\t , 'FEEDNEWS': '1'
\t , 'CURRENT': '2'
\t , 'LOADCOMPLATE': '3'
\t , 'COINPAIRS': '4'
\t , 'CURRENTAGG': '5'
\t , 'TOPLIST': '6'
\t , 'TOPLISTCHANGE': '7'
\t , 'ORDERBOOK': '8'
\t , 'FULLORDERBOOK': '9'
\t , 'ACTIVATION': '10'
\t , 'TRADECATCHUP': '100'
\t , 'NEWSCATCHUP': '101'
\t , 'TRADECATCHUPCOMPLETE': '300'
\t , 'NEWSCATCHUPCOMPLETE': '301'
};
CCC.STATIC.CURRENCY = CCC.STATIC.CURRENCY || {};
CCC.STATIC.CURRENCY.SYMBOL = {
\t 'BTC': '?'
\t , 'LTC': '?'
\t , 'DAO': 'Ð'
\t , 'USD': '$'
\t , 'CNY': '¥'
\t , 'EUR': '€'
\t , 'GBP': '£'
\t , 'JPY': '¥'
\t , 'PLN': 'z?'
\t , 'RUB': '?'
\t , 'ETH': '?'
\t , 'GOLD': 'Gold g'
\t , 'INR': '?'
\t , 'BRL': 'R$'
};
CCC.STATIC.CURRENCY.getSymbol = function (symbol) {
\t return CCC.STATIC.CURRENCY.SYMBOL[symbol] || symbol;
};
CCC.STATIC.UTIL = {
\t exchangeNameMapping: {
\t \t 'CCCAGG': 'CryptoCompare Index',
\t \t 'BTCChina': 'BTCC'
\t },
\t isMobile: function (userAgent) {
\t \t if (/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|ipad|iris|kindle|Android|Silk|lge |maemo|midp|mmp|netfront|opera m(ob|in)i|palm(os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows (ce|phone)|xda|xiino/i.test(userAgent)
\t \t \t || /1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s)|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp(i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac(|\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt(|\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg(g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v)|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v)|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-|)|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(userAgent.substr(0, 4)))
\t \t \t return true;
\t \t return false;
\t },
\t convertToMB: function (bytes) {
\t \t return (parseInt(bytes, 10)/1024/1024).toFixed(2) + ' MB';
\t },
\t getNameForExchange: function (exchangeName) {
\t \t if (this.exchangeNameMapping.hasOwnProperty(exchangeName)) {
\t \t \t return this.exchangeNameMapping[exchangeName];
\t \t }
\t \t return exchangeName;
\t },
\t noExponents: function (value) {
\t \t var data = String(value).split(/[eE]/);
\t \t if (data.length == 1) return data[0];
\t \t var z = '', sign = value < 0 ? '-' : '',
\t \t \t str = data[0].replace('.', ''),
\t \t \t mag = Number(data[1]) + 1;
\t \t if (mag < 0) {
\t \t \t z = sign + '0.';
\t \t \t while (mag++) z += '0';
\t \t \t return z + str.replace(/^\-/, '');
\t \t }
\t \t mag -= str.length;
\t \t while (mag--) z += '0';
\t \t return str + z;
\t },
\t reduceFloatVal: function (value) {
\t \t value = parseFloat(value);
\t \t if (value > 1) {
\t \t \t value = Math.round(value * 100)/100;
\t \t \t return value;
\t \t }
\t \t if (value >= 0.00001000) {
\t \t \t return parseFloat(value.toPrecision(4));
\t \t }
\t \t if (value >= 0.00000100) {
\t \t \t return parseFloat(value.toPrecision(3));
\t \t }
\t \t if (value >= 0.00000010) {
\t \t \t return parseFloat(value.toPrecision(2));
\t \t }
\t \t return parseFloat(value.toPrecision(1));
\t },
\t reduceReal: function (value) {
\t \t value = parseFloat(value);
\t \t return parseFloat(value.toFixed(8));
\t },
\t convertCurrentKeyToAll: function (key) {
\t \t var valuesArray = key.split("~");
\t \t valuesArray[0] = CCC.STATIC.TYPE.CURRENTAGG;
\t \t valuesArray[1] = 'CCCAGG';
\t \t return valuesArray.join('~');
\t },
\t convertCurrentKeyToTrade: function (key) {
\t \t var valuesArray = key.split("~");
\t \t valuesArray[0] = CCC.STATIC.TYPE.TRADE;
\t \t return valuesArray.join('~');
\t },
\t convertValueToDisplay: function (symbol, value, filterNumberFunctionAngularJS, type, fullNumbers) {
\t \t var prefix = '';
\t \t var valueSign = 1;
\t \t value = parseFloat(value);
\t \t var valueAbs = Math.abs(value);
\t \t var decimalsOnBigNumbers = 2;
\t \t var decimalsOnNormalNumbers = 2;
\t \t var decimalsOnSmallNumbers = 4;
\t \t if (fullNumbers === true) {
\t \t \t decimalsOnBigNumbers = 2;
\t \t \t decimalsOnNormalNumbers = 0;
\t \t \t decimalsOnSmallNumbers = 4;
\t \t }
\t \t if (type == "8decimals") {
\t \t \t decimalsOnBigNumbers = 4;
\t \t \t decimalsOnNormalNumbers = 8;
\t \t \t decimalsOnSmallNumbers = 8;
\t \t \t if (value < 0.0001 && value >= 0.00001) { decimalsOnSmallNumbers = 4; }
\t \t \t if (value < 0.001 && value >= 0.0001) { decimalsOnSmallNumbers = 5; }
\t \t \t if (value < 0.01 && value >= 0.001) { decimalsOnSmallNumbers = 6; }
\t \t \t if (value < 0.1 && value >= 0.01) { decimalsOnSmallNumbers = 7; }
\t \t }
\t \t if (symbol != '') { prefix = symbol + ' '; }
\t \t if (value < 0) { valueSign = -1; }
\t \t if (value == 0) { return prefix + '0'; }
\t \t if (value < 0.00001000 && value >= 0.00000100 && decimalsOnSmallNumbers > 3) {
\t \t \t decimalsOnSmallNumbers = 3;
\t \t }
\t \t if (value < 0.00000100 && value >= 0.00000010 && decimalsOnSmallNumbers > 2) {
\t \t \t decimalsOnSmallNumbers = 2;
\t \t }
\t \t if (value < 0.00000010 && decimalsOnSmallNumbers > 1) {
\t \t \t decimalsOnSmallNumbers = 1;
\t \t }
\t \t if (type == "short" || type == "8decimals") {
\t \t \t if (valueAbs > 10000000000) {
\t \t \t \t valueAbs = valueAbs/1000000000;
\t \t \t \t return prefix + filterNumberFunctionAngularJS(valueSign * valueAbs, decimalsOnBigNumbers) + ' B';
\t \t \t }
\t \t \t if (valueAbs > 10000000) {
\t \t \t \t valueAbs = valueAbs/1000000;
\t \t \t \t return prefix + filterNumberFunctionAngularJS(valueSign * valueAbs, decimalsOnBigNumbers) + ' M';
\t \t \t }
\t \t \t if (valueAbs > 10000) {
\t \t \t \t valueAbs = valueAbs/1000;
\t \t \t \t return prefix + filterNumberFunctionAngularJS(valueSign * valueAbs, decimalsOnBigNumbers) + ' K';
\t \t \t }
\t \t \t if (type == "8decimals" && valueAbs >= 100) {
\t \t \t \t return prefix + filterNumberFunctionAngularJS(valueSign * valueAbs, decimalsOnBigNumbers);
\t \t \t }
\t \t \t if (valueAbs >= 1) {
\t \t \t \t return prefix + filterNumberFunctionAngularJS(valueSign * valueAbs, decimalsOnNormalNumbers);
\t \t \t }
\t \t \t return prefix + (valueSign * valueAbs).toPrecision(decimalsOnSmallNumbers);
\t \t } else {
\t \t \t if (valueAbs >= 1) {
\t \t \t \t return prefix + filterNumberFunctionAngularJS(valueSign * valueAbs, decimalsOnNormalNumbers);
\t \t \t }
\t \t \t return prefix + this.noExponents((valueSign * valueAbs).toPrecision(decimalsOnSmallNumbers));
\t \t }
\t }
};
CCC.TRADE = CCC.TRADE || {};
/*
trade fields binary values always in the last ~
*/
CCC.TRADE.FLAGS = {
\t 'SELL': 0x1 // hex for binary 1
\t , 'BUY': 0x2 // hex for binary 10
\t , 'UNKNOWN': 0x4 // hex for binary 100
}
CCC.TRADE.FIELDS = {
\t 'T': 0x0 // hex for binary 0, it is a special case of fields that are always there TYPE
\t , 'M': 0x0 // hex for binary 0, it is a special case of fields that are always there MARKET
\t , 'FSYM': 0x0 // hex for binary 0, it is a special case of fields that are always there FROM SYMBOL
\t , 'TSYM': 0x0 // hex for binary 0, it is a special case of fields that are always there TO SYMBOL
\t , 'F': 0x0 // hex for binary 0, it is a special case of fields that are always there FLAGS
\t , 'ID': 0x1 // hex for binary 1 ID
\t , 'TS': 0x2 // hex for binary 10 TIMESTAMP
\t , 'Q': 0x4 // hex for binary 100 QUANTITY
\t , 'P': 0x8 // hex for binary 1000 PRICE
\t , 'TOTAL': 0x10 // hex for binary 10000 TOTAL
};
CCC.TRADE.DISPLAY = CCC.TRADE.DISPLAY || {};
CCC.TRADE.DISPLAY.FIELDS = {
\t 'T': { "Show": false }
\t , 'M': { "Show": true, 'Filter': 'Market' }
\t , 'FSYM': { "Show": true, 'Filter': 'CurrencySymbol' }
\t , 'TSYM': { "Show": true, 'Filter': 'CurrencySymbol' }
\t , 'F': { "Show": true, 'Filter': 'TradeFlag' }
\t , 'ID': { "Show": true, 'Filter': 'Text' }
\t , 'TS': { 'Show': true, 'Filter': 'Date', 'Format': 'yyyy MMMM dd HH:mm:ss' }
\t , 'Q': { 'Show': true, 'Filter': 'Number', 'Symbol': 'FSYM' }
\t , 'P': { 'Show': true, 'Filter': 'Number', 'Symbol': 'TSYM' }
\t , 'TOTAL': { 'Show': true, 'Filter': 'Number', 'Symbol': 'TSYM' }
};
CCC.TRADE.pack = function (tradeObject) {
\t var mask = 0;
\t var packedTrade = '';
\t for (var field in tradeObject) {
\t \t packedTrade += '~' + tradeObject[field];
\t \t mask |= this.FIELDS[field];
\t }
\t return packedTrade.substr(1) + '~' + mask.toString(16);
};
CCC.TRADE.unpack = function (tradeString) {
\t var valuesArray = tradeString.split("~");
\t var valuesArrayLenght = valuesArray.length;
\t var mask = valuesArray[valuesArrayLenght - 1];
\t var maskInt = parseInt(mask, 16);
\t var unpackedTrade = {};
\t var currentField = 0;
\t for (var property in this.FIELDS) {
\t \t if (this.FIELDS[property] === 0) {
\t \t \t unpackedTrade[property] = valuesArray[currentField];
\t \t \t currentField++;
\t \t }
\t \t else if (maskInt & this.FIELDS[property]) {
\t \t \t unpackedTrade[property] = valuesArray[currentField];
\t \t \t currentField++;
\t \t }
\t }
\t return unpackedTrade;
}
CCC.TRADE.getKey = function (tradeObject) {
\t return tradeObject['T'] + '~' + tradeObject['M'] + '~' + tradeObject['FSYM'] + '~' + tradeObject['TSYM'];
};
CCC.CURRENT = CCC.CURRENT || {};
/*
current fields mask values always in the last ~
*/
CCC.CURRENT.FLAGS = {
\t 'PRICEUP': 0x1 // hex for binary 1
\t , 'PRICEDOWN': 0x2 // hex for binary 10
\t , 'PRICEUNCHANGED': 0x4 // hex for binary 100
\t , 'BIDUP': 0x8 // hex for binary 1000
\t , 'BIDDOWN': 0x10 // hex for binary 10000
\t , 'BIDUNCHANGED': 0x20 // hex for binary 100000
\t , 'OFFERUP': 0x40 // hex for binary 1000000
\t , 'OFFERDOWN': 0x80 // hex for binary 10000000
\t , 'OFFERUNCHANGED': 0x100 // hex for binary 100000000
\t , 'AVGUP': 0x200 // hex for binary 1000000000
\t , 'AVGDOWN': 0x400 // hex for binary 10000000000
\t , 'AVGUNCHANGED': 0x800 // hex for binary 100000000000
};
CCC.CURRENT.FIELDS = {
\t 'TYPE': 0x0 // hex for binary 0, it is a special case of fields that are always there
\t , 'MARKET': 0x0 // hex for binary 0, it is a special case of fields that are always there
\t , 'FROMSYMBOL': 0x0 // hex for binary 0, it is a special case of fields that are always there
\t , 'TOSYMBOL': 0x0 // hex for binary 0, it is a special case of fields that are always there
\t , 'FLAGS': 0x0 // hex for binary 0, it is a special case of fields that are always there
\t , 'PRICE': 0x1 // hex for binary 1
\t , 'BID': 0x2 // hex for binary 10
\t , 'OFFER': 0x4 // hex for binary 100
\t , 'LASTUPDATE': 0x8 // hex for binary 1000
\t , 'AVG': 0x10 // hex for binary 10000
\t , 'LASTVOLUME': 0x20 // hex for binary 100000
\t , 'LASTVOLUMETO': 0x40 // hex for binary 1000000
\t , 'LASTTRADEID': 0x80 // hex for binary 10000000
\t , 'VOLUMEHOUR': 0x100 // hex for binary 100000000
\t , 'VOLUMEHOURTO': 0x200 // hex for binary 1000000000
\t , 'VOLUME24HOUR': 0x400 // hex for binary 10000000000
\t , 'VOLUME24HOURTO': 0x800 // hex for binary 100000000000
\t , 'OPENHOUR': 0x1000 // hex for binary 1000000000000
\t , 'HIGHHOUR': 0x2000 // hex for binary 10000000000000
\t , 'LOWHOUR': 0x4000 // hex for binary 100000000000000
\t , 'OPEN24HOUR': 0x8000 // hex for binary 1000000000000000
\t , 'HIGH24HOUR': 0x10000 // hex for binary 10000000000000000
\t , 'LOW24HOUR': 0x20000 // hex for binary 100000000000000000
\t , 'LASTMARKET': 0x40000 // hex for binary 1000000000000000000, this is a special case and will only appear on CCCAGG messages
};
CCC.CURRENT.DISPLAY = CCC.CURRENT.DISPLAY || {};
CCC.CURRENT.DISPLAY.FIELDS = {
\t 'TYPE': { 'Show': false }
\t , 'MARKET': { 'Show': true, 'Filter': 'Market' }
\t , 'FROMSYMBOL': { 'Show': false }
\t , 'TOSYMBOL': { 'Show': false }
\t , 'FLAGS': { 'Show': false }
\t , 'PRICE': { 'Show': true, 'Filter': 'Number', 'Symbol': 'TOSYMBOL' }
\t , 'BID': { 'Show': true, 'Filter': 'Number', 'Symbol': 'TOSYMBOL' }
\t , 'OFFER': { 'Show': true, 'Filter': 'Number', 'Symbol': 'TOSYMBOL' }
\t , 'LASTUPDATE': { 'Show': true, 'Filter': 'Date', 'Format': 'yyyy MMMM dd HH:mm:ss' }
\t , 'AVG': { 'Show': true, ' Filter': 'Number', 'Symbol': 'TOSYMBOL' }
\t , 'LASTVOLUME': { 'Show': true, 'Filter': 'Number', 'Symbol': 'FROMSYMBOL' }
\t , 'LASTVOLUMETO': { 'Show': true, 'Filter': 'Number', 'Symbol': 'TOSYMBOL' }
\t , 'LASTTRADEID': { 'Show': true, 'Filter': 'String' }
\t , 'VOLUMEHOUR': { 'Show': true, 'Filter': 'Number', 'Symbol': 'FROMSYMBOL' }
\t , 'VOLUMEHOURTO': { 'Show': true, 'Filter': 'Number', 'Symbol': 'TOSYMBOL' }
\t , 'VOLUME24HOUR': { 'Show': true, 'Filter': 'Number', 'Symbol': 'FROMSYMBOL' }
\t , 'VOLUME24HOURTO': { 'Show': true, 'Filter': 'Number', 'Symbol': 'TOSYMBOL' }
\t , 'OPENHOUR': { 'Show': true, 'Filter': 'Number', 'Symbol': 'TOSYMBOL' }
\t , 'HIGHHOUR': { 'Show': true, 'Filter': 'Number', 'Symbol': 'TOSYMBOL' }
\t , 'LOWHOUR': { 'Show': true, 'Filter': 'Number', 'Symbol': 'TOSYMBOL' }
\t , 'OPEN24HOUR': { 'Show': true, 'Filter': 'Number', 'Symbol': 'TOSYMBOL' }
\t , 'HIGH24HOUR': { 'Show': true, 'Filter': 'Number', 'Symbol': 'TOSYMBOL' }
\t , 'LOW24HOUR': { 'Show': true, 'Filter': 'Number', 'Symbol': 'TOSYMBOL' }
\t , 'LASTMARKET': { 'Show': true, 'Filter': 'String' }
};
CCC.CURRENT.pack = function (currentObject) {
\t var mask = 0;
\t var packedCurrent = '';
\t for (var property in this.FIELDS) {
\t \t if (currentObject.hasOwnProperty(property)) {
\t \t \t packedCurrent += '~' + currentObject[property];
\t \t \t mask |= this.FIELDS[property];
\t \t }
\t }
\t //removing first character beacsue it is a ~
\t return packedCurrent.substr(1) + '~' + mask.toString(16);
};
CCC.CURRENT.unpack = function (value) {
\t var valuesArray = value.split("~");
\t var valuesArrayLenght = valuesArray.length;
\t var mask = valuesArray[valuesArrayLenght - 1];
\t var maskInt = parseInt(mask, 16);
\t var unpackedCurrent = {};
\t var currentField = 0;
\t for (var property in this.FIELDS) {
\t \t if (this.FIELDS[property] === 0) {
\t \t \t unpackedCurrent[property] = valuesArray[currentField];
\t \t \t currentField++;
\t \t }
\t \t else if (maskInt & this.FIELDS[property]) {
\t \t \t //i know this is a hack, for cccagg, future code please don't hate me:(, i did this to avoid
\t \t \t //subscribing to trades as well in order to show the last market
\t \t \t if (property === 'LASTMARKET') {
\t \t \t \t unpackedCurrent[property] = valuesArray[currentField];
\t \t \t } else {
\t \t \t \t unpackedCurrent[property] = parseFloat(valuesArray[currentField]);
\t \t \t }
\t \t \t currentField++;
\t \t }
\t }
\t return unpackedCurrent;
};
CCC.CURRENT.getKey = function (currentObject) {
\t return currentObject['TYPE'] + '~' + currentObject['MARKET'] + '~' + currentObject['FROMSYMBOL'] + '~' + currentObject['TOSYMBOL'];
};
CCC.CURRENT.getKeyFromStreamerData = function (streamerData) {
\t var valuesArray = streamerData.split("~");
\t return valuesArray[0] + '~' + valuesArray[1] + '~' + valuesArray[2] + '~' + valuesArray[3];
};
CCC.noExponents = function (value) {
\t var data = String(value).split(/[eE]/);
\t if (data.length == 1) return data[0];
\t var z = '', sign = value < 0 ? '-' : '',
\t \t str = data[0].replace('.', ''),
\t \t mag = Number(data[1]) + 1;
\t if (mag < 0) {
\t \t z = sign + '0.';
\t \t while (mag++) z += '0';
\t \t return z + str.replace(/^\-/, '');
\t }
\t mag -= str.length;
\t while (mag--) z += '0';
\t return str + z;
};
CCC.filterNumberFunctionPolyfill = function (value, decimals) {
\t var decimalsDenominator = Math.pow(10, decimals);
\t var numberWithCorrectDecimals = Math.round(value * decimalsDenominator)/decimalsDenominator;
\t var parts = numberWithCorrectDecimals.toString().split(".");
\t parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ",");
\t return parts.join(".");
}
CCC.convertValueToDisplay = function (symbol, value, type, fullNumbers) {
\t var prefix = '';
\t var valueSign = 1;
\t value = parseFloat(value);
\t var valueAbs = Math.abs(value);
\t var decimalsOnBigNumbers = 2;
\t var decimalsOnNormalNumbers = 2;
\t var decimalsOnSmallNumbers = 4;
\t if (fullNumbers === true) {
\t \t decimalsOnBigNumbers = 2;
\t \t decimalsOnNormalNumbers = 0;
\t \t decimalsOnSmallNumbers = 4;
\t }
\t if (symbol != '') {
\t \t prefix = symbol + ' ';
\t }
\t if (value < 0) {
\t \t valueSign = -1;
\t }
\t if (value == 0) {
\t \t return prefix + '0';
\t }
\t if (value < 0.00001000 && value >= 0.00000100 && decimalsOnSmallNumbers > 3) {
\t \t decimalsOnSmallNumbers = 3;
\t }
\t if (value < 0.00000100 && value >= 0.00000010 && decimalsOnSmallNumbers > 2) {
\t \t decimalsOnSmallNumbers = 2;
\t }
\t if (value < 0.00000010 && value >= 0.00000001 && decimalsOnSmallNumbers > 1) {
\t \t decimalsOnSmallNumbers = 1;
\t }
\t if (type == "short") {
\t \t if (valueAbs > 10000000000) {
\t \t \t valueAbs = valueAbs/1000000000;
\t \t \t return prefix + CCC.filterNumberFunctionPolyfill(valueSign * valueAbs, decimalsOnBigNumbers) + ' B';
\t \t }
\t \t if (valueAbs > 10000000) {
\t \t \t valueAbs = valueAbs/1000000;
\t \t \t return prefix + CCC.filterNumberFunctionPolyfill(valueSign * valueAbs, decimalsOnBigNumbers) + ' M';
\t \t }
\t \t if (valueAbs > 10000) {
\t \t \t valueAbs = valueAbs/1000;
\t \t \t return prefix + CCC.filterNumberFunctionPolyfill(valueSign * valueAbs, decimalsOnBigNumbers) + ' K';
\t \t }
\t \t if (valueAbs >= 1) {
\t \t \t return prefix + CCC.filterNumberFunctionPolyfill(valueSign * valueAbs, decimalsOnNormalNumbers);
\t \t }
\t \t return prefix + (valueSign * valueAbs).toPrecision(decimalsOnSmallNumbers);
\t } else {
\t \t if (valueAbs >= 1) {
\t \t \t return prefix + CCC.filterNumberFunctionPolyfill(valueSign * valueAbs, decimalsOnNormalNumbers);
\t \t }
\t \t return prefix + CCC.noExponents((valueSign * valueAbs).toPrecision(decimalsOnSmallNumbers));
\t }
};
问题可能是服务器片面,因为我也无法建立连接(即使是打他们的服务器时,直接用'websocket.connect('WSS ://streamer.cryptocompare.com/socket.io/websocket')')。 – rob
另外值得注意的是,当使用[JavaScript客户端](https://github.com/cryptoqween/cryptoqween.github.io/blob/master/streamer/current/stream.js#L68)时,它连接时没有错误 – rob
是但是我认为我们的问题是缺乏一个很好的例子。 Python的websockets和socketio的实现似乎是一个混乱。 –