Skip to content

Instantly share code, notes, and snippets.

@fimkrypto fimkrypto/FIMKSocket.js
Last active Aug 29, 2015

Embed
What would you like to do?
WebSocket wrapper for FIMkrypto
(function () {
var call_id = 0, timeout_ms = 30 * 1000, available_methods = [
'callAPIFunction','getAccountAssets','getAccountCurrencies','getActivity', 'getRecentTransactions',
'getComments', 'getCommentCount', 'getAccountPosts', 'getAssetPosts', 'getAccounts', 'getAccount',
'getAsset', 'getForgingStats', 'getActivityStatistics','getAskOrder','getBidOrder','getAssetChartData',
'getAssetOrders','getAssetTrades','getMyOpenOrders','getBlockchainState'
];
function FIMKSocket(url) {
this.topics = {};
this.callbacks = {};
this.onready = [];
this.websocket = new WebSocket(url);
this.websocket.onopen = createOnOpenHandler(this);
this.websocket.onmessage = createOnMessageHandler(this);
}
FIMKSocket.prototype = {
/* Websocket must be open before we use it */
ready: function (callback) {
if (this.websocket && this.websocket.readyState == 1) {
callback.call(null, this);
}
else {
this.onready.push(callback);
}
},
/* Close the socket connection */
close: function () {
if (this.websocket) {
this.websocket.close();
delete this.websocket;
}
},
/* Subscribe to a topic */
subscribe: function (topic, callback) {
topic = topic.toUpperCase();
if (!this.topics[topic]) {
this.topics[topic] = [];
this.websocket.send(JSON.stringify(['subscribe', topic]));
}
this.topics[topic].push(callback);
},
/* UnSubscribe from a topic */
unsubscribe: function (topic, callback) {
topic = topic.toUpperCase();
if (this.topics[topic]) {
this.topics[topic] = this.topics[topic].filter(function (cb) {
return cb !== callback;
});
if (this.topics[topic].length == 0) {
delete this.topics[topic];
this.websocket.send(JSON.stringify(['unsubscribe', topic]));
}
}
}
};
/* Install available API methods on the object prototype */
for (var i=0; i<available_methods.length; i++) {
FIMKSocket.prototype[available_methods[i]] = createAPIMethod(available_methods[i]);
}
function createAPIMethod(name) {
return function (argv, callback, failure) {
rpc(this, name, argv, callback, failure);
}
}
/* Calls a method on the remote server. */
function rpc(socket, method, argv, callback, failure) {
var id = String(call_id++);
socket.callbacks[id] = {
callback: callback,
failure: failure,
timeout: setTimeout(createTimeoutHandler(socket, id), timeout_ms)
};
socket.websocket.send(JSON.stringify(['call', id, method, argv||{}]));
}
/* Handler for WebSocket.onopen */
function createOnOpenHandler(socket) {
return function (event) {
for (var i=0; i<socket.onready.length; i++) {
socket.onready[i].call(null, socket);
}
socket.onready.length = 0;
}
}
/* Handler for WebSocket.onmessage */
function createOnMessageHandler(socket) {
return function (event) {
var message = event.data;
if (message == "pong") { return }
var data = JSON.parse(event.data);
if (!Array.isArray(data)) {
throw new Error('FIMKSocket - Expected an array', event);
}
switch (data[0]) {
case "response":
var call_id = data[1];
var argv = data[2];
if (socket.callbacks[call_id]) {
var callback = socket.callbacks[call_id].callback;
clearTimeout(socket.callbacks[call_id].timeout);
delete socket.callbacks[call_id];
callback.call(null, argv);
}
break;
case "notify":
var topic = data[1];
var argv = data[2];
var listeners = socket.topics[topic];
if (listeners) {
for (var i=0; i<listeners.length; i++) {
listeners[i].call(null, argv);
}
}
break;
default:
throw new Error('FIMKSocket - Unsupported operation', event);
}
}
}
/* Handler for a timedout rpc call */
function createTimeoutHandler(socket, call_id) {
return function () {
var failure = socket.callbacks[call_id].failure;
if (failure) {
failure.call(null, { "error": "timeout" });
}
delete socket.callbacks[call_id];
}
}
window.FIMKSocket = FIMKSocket;
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.