Last active
March 23, 2016 22:17
-
-
Save jason-s13r/7e547987c77cef5aa9fa to your computer and use it in GitHub Desktop.
angular websockets json-rpc2 service that uses [angular-websockets](https://github.com/AngularClass/angular-websocket). JSFiddle example: https://jsfiddle.net/master5o1/bxvauLcw/
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
angular.module('ngWebsocketRpc', ['ngWebSocket', 'guid']) | |
.factory('$rpc', ['$websocket', '$q', 'guid', function($websocket, $q, guid) { | |
var seconds = 1000; | |
var history = {}; | |
var methods = {}; | |
var $ws; | |
var handlers = { | |
onOpen: angular.noop, | |
onClose: angular.noop, | |
onError: angular.noop | |
}; | |
var rpcErrors = { | |
ParseError: RpcError(-32700, 'Parse error'), | |
InvalidRequest: RpcError(-32600, 'Invalid Request'), | |
MethodNotFound: RpcError(-32601, 'Method not found'), | |
InvalidParams: RpcError(-32602, 'Invalid params'), | |
InternalError: RpcError(-32603, 'Internal error'), | |
ServerError: RpcError(-32000, 'Server Error'), | |
}; | |
function open(url) { | |
$ws = $websocket(url); | |
$ws.onMessage(messageRouter); | |
} | |
function close(force) { | |
return $ws.close(force); | |
} | |
function messageRouter(event, message) { | |
message = JSON.parse(event.data); | |
if (!!message.method) { | |
handlerMethodCall(event, message); | |
return; | |
} | |
handleCallResponse(event, message); | |
} | |
function handleCallResponse(event, message){ | |
var call = history[message.id]; | |
if (!!message.result) { | |
call.deferred.resolve(message.result, message, event); | |
return; | |
} | |
call.deferred.reject(message.error, message, event); | |
} | |
function handlerMethodCall(event, message) { | |
var response = { | |
"jsonrpc": "2.0", | |
"id": message.id | |
}; | |
var params = message.params; | |
var fn = methods[message.method]; | |
if (typeof fn === 'function'){ | |
response = angular.extend(response, fn(params)); | |
} else { | |
response = angular.extend(response, { | |
error: rpcErrors.MethodNotFound | |
}); | |
} | |
var promise = $ws.send(JSON.stringify(response)); | |
} | |
function callMethod(method, parameters) { | |
var id = guid(); | |
var data = { | |
"jsonrpc": "2.0", | |
"method": method, | |
"params": parameters, | |
"id": id | |
}; | |
var deferred = $q.defer(); | |
var send = $ws.send(JSON.stringify(data)); | |
history[id] = { | |
call: data, | |
messages: [], | |
send: send, | |
deferred: deferred | |
}; | |
// cancel if somehow it doesn't make it to the websocket. | |
send.then(angular.noop, deferred.reject); | |
return deferred.promise; | |
} | |
function exposeMethod(method, handler){ | |
methods[method] = handler; | |
} | |
function RpcError(code, message) { | |
return { | |
error: { | |
code: code, | |
message: message | |
} | |
}; | |
} | |
function RpcResult(result) { | |
return { | |
result: result | |
}; | |
} | |
function onEventHandlerFactory(eventName) { | |
return function(fn){ | |
$ws[eventName](fn); | |
}; | |
} | |
return { | |
$ws: $ws, | |
open: open, | |
close: close, | |
onOpen: onEventHandlerFactory('onOpen'), | |
onClose: onEventHandlerFactory('onClose'), | |
onError: onEventHandlerFactory('onError'), | |
call: callMethod, | |
expose: exposeMethod, | |
_: { | |
Result: RpcResult, | |
Errors: rpcErrors | |
} | |
}; | |
}]); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
angular.module('guid', []) | |
.factory('guid', [function() { | |
return function Guid() { | |
function S4() { | |
var num = (((1 + Math.random()) * 0x10000) | 0); | |
if (!!crypto && !!crypto.getRandomValues) { | |
num = crypto.getRandomValues(new Uint32Array(1))[0]; | |
} | |
return num.toString(16).substring(1, 5); | |
} | |
// x = 4 characters, y = 3 characters | |
return 'xx-x-4y-x-xxx'.replace(/[xy]/g, function(v) { | |
return v === 'x' ? S4() : S4().substring(0, 3); | |
}).toLowerCase(); | |
}; | |
}]); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment