wsrpc.js 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. /*
  2. Goal having something like:
  3. wsrpc.Connect("/ws");
  4. wsrpc.Connect("ws://127.0.0.1/ws");
  5. obj = {
  6. method1:function() {
  7. //Hello
  8. }
  9. }
  10. wsrpc.Export(obj);
  11. */
  12. function WsRpc() {
  13. var ctx = this
  14. this._requests = {}
  15. this.connect = function(loc) {
  16. var ws = this.ws = new WebSocket(loc)
  17. ws.onopen = function() {
  18. ctx._requests = {}
  19. ctx.connected = true;
  20. if(ctx.onopen != undefined) {
  21. ctx.onopen(ctx)
  22. }
  23. }
  24. ws.onmessage = function(evt) {
  25. //console.log("RCV:",evt.data)
  26. var obj = JSON.parse(evt.data)
  27. var arrObj = [].concat(obj); // if object add, if array concat
  28. for( var i = 0; i <arrObj.length; i++) {
  29. ctx.process(arrObj[i]);
  30. }
  31. }
  32. ws.onerror = function() { }
  33. ws.onclose = function() {
  34. if(ctx.connected == true) {
  35. ctx.connected = false;
  36. if(ctx.onclose != undefined) {
  37. ctx.onclose(ctx)
  38. }
  39. }
  40. // Retry
  41. setTimeout(function() {
  42. ctx.connect(loc)
  43. },3000) // 3 seconds reconnect
  44. }
  45. }
  46. this.process = function(obj) {
  47. if (obj.op == "call") {
  48. if(obj.method == undefined || this._exports[obj.method] == undefined) {
  49. //TODO: Send objet to inform error
  50. return
  51. }
  52. function response(data) {
  53. var dataObj = {
  54. "op":"response",
  55. "reqId":obj.reqId,
  56. "data":data
  57. }
  58. ctx.ws.send(JSON.stringify(dataObj));
  59. }
  60. var nparams = [].concat(response,obj.param)
  61. this._exports[obj.method].apply(this._exports[obj.method],nparams)
  62. }
  63. if( obj.op == "response" ) {
  64. //console.log("Receiving response for:", obj.reqId)
  65. ctx._requests[obj.reqId](obj.data)
  66. delete ctx._requests[obj.reqId]
  67. }
  68. }
  69. this.call = function(method) {
  70. var aparam = Array.prototype.slice.call(arguments,1)
  71. return new Promise(function(resolve,reject) {
  72. if(ctx.connected == false ) {
  73. reject(Error("Not connected"))
  74. }
  75. var uuidStr = uuid();
  76. var callObj = {
  77. "reqId":uuidStr,
  78. "op":"call",
  79. "method":method,
  80. "param":aparam
  81. }
  82. ctx._requests[uuidStr] = resolve;
  83. //console.log("Sending a call:", method)
  84. ctx.ws.send(JSON.stringify(callObj));
  85. })
  86. }
  87. this.export = function(obj){
  88. this._exports = obj;
  89. }
  90. return this
  91. }
  92. function uuid() {
  93. var ret = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
  94. var r = Math.random()*16|0, v = c == 'x' ? r : (r&0x3|0x8);
  95. return v.toString(16);
  96. });
  97. return ret;
  98. }