ChipMaster's trial hacks on C++CMS starting with v1.2.1. Not sure I'll follow on with the v2 since it looks to be breaking and mostly frivolous.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

178 lines
4.8 KiB

  1. //
  2. // Copyright (c) 2011 Artyom Beilis (Tonkikh)
  3. //
  4. // Distributed under the Boost Software License, Version 1.0. (See
  5. // accompanying file LICENSE_1_0.txt or copy at
  6. // http://www.boost.org/LICENSE_1_0.txt)
  7. //
  8. ///
  9. /// Create new JsonRPC service.
  10. ///
  11. /// Constructor:
  12. /// Parameters:
  13. /// - uri - string - service URI
  14. /// - function_methods - optional array of strings - method names that return results
  15. /// - notification_methods - optional array of strings - notification method names
  16. ///
  17. /// Useful methods:
  18. ///
  19. /// addRPCMethod(name,id)
  20. /// Creates new method with named name
  21. /// Parameters:
  22. /// - name - new method name
  23. /// - id - JSONRPC id. It should be null for notification methods
  24. /// and it should be some integer or string for function methods
  25. ///
  26. /// Each method given in the constructor would have following properties:
  27. ///
  28. /// on_error(e) - Returned error, where e.type is one of 'transport', 'protocol', 'response' and
  29. /// e.error is the error object.
  30. /// on_result(r) - Returned method result, or on_result() - for notifications.
  31. ///
  32. /// For example
  33. ///
  34. /// var rpc = new JsonRPC('/chat',['getValue','getStatistics'],['updateValue']);
  35. ///
  36. /// // Asynchronouse method
  37. ///
  38. /// rpc.getValue.on_error = function(e) { alert('Error:' + e.error); }
  39. /// rpc.getValue.on_result = function(r) { alert(r); }
  40. ///
  41. /// rpc.getValue();
  42. ///
  43. /// // Synchronous method
  44. ///
  45. /// // not setting callbacks or setting on_error and on_result to null
  46. /// // makes them synchronous rpc calls. For example;
  47. ///
  48. /// alert(rpc.getStatistics());
  49. /// rpc.updateValue(10);
  50. ///
  51. ///
  52. function JsonRPC(uri,function_methods,notification_methods) {
  53. if(!(this instanceof JsonRPC))
  54. return new JsonRPC(uri,function_methods,notification_methods);
  55. this.uri = uri;
  56. if(typeof function_methods != 'undefined') {
  57. for(var i=0;i<function_methods.length;i++)
  58. {
  59. this.addRPCMethod(function_methods[i],i);
  60. }
  61. }
  62. if(typeof notification_methods != 'undefined') {
  63. for(var i=0;i<notification_methods.length;i++)
  64. {
  65. this.addRPCMethod(notification_methods[i],null);
  66. }
  67. }
  68. }
  69. JsonRPC.prototype.getXHR = function() {
  70. // Create new XMLHttpRequest for all browsers
  71. var xhr;
  72. if(typeof XMLHttpRequest != "undefined") {
  73. xhr = new XMLHttpRequest();
  74. }
  75. else {
  76. try { xhr = new ActiveXObject("Msxml2.XMLHTTP.6.0"); }catch(e){}
  77. try { xhr = new ActiveXObject("Msxml2.XMLHTTP.3.0"); }catch(e){}
  78. try { xhr = new ActiveXObject("Microsoft.XMLHTTP"); }catch(e){}
  79. throw new Error("No XML HTTP Rewquest support");
  80. }
  81. return xhr;
  82. }
  83. JsonRPC.prototype.runXHR = function(xhr,name,id,params) {
  84. // Perform actual XML HTTP Request
  85. xhr.setRequestHeader("Content-Type","application/json");
  86. var request = {'id' : id,'method' : name, 'params' : params };
  87. var requestText = JSON.stringify(request);
  88. xhr.send(requestText);
  89. }
  90. JsonRPC.prototype.syncCall = function(name,id,params) {
  91. // Synchronous method call name = method name
  92. // id null for notifcation something for functions
  93. // params - array of parameters
  94. var xhr = this.getXHR();
  95. xhr.open("post",this.uri,false);
  96. this.runXHR(xhr,name,id,params);
  97. if(xhr.status!=200)
  98. throw Error('Invalid response:' + xhr.status);
  99. if(id!=null) {
  100. var response = null;
  101. try {
  102. response = JSON.parse(xhr.responseText);
  103. }
  104. catch(e) {
  105. throw Error('Invalid JSON-RPC response');
  106. }
  107. if(response.error != null)
  108. throw Error(response.error);
  109. return response.result;
  110. }
  111. }
  112. JsonRPC.prototype.asyncCall = function(name,id,params,on_result,on_error) {
  113. // Asynchronous method call name = method name
  114. // id null for notifcation something for functions
  115. // params - array of parameters
  116. // on_result and on_error - the callbacks
  117. //
  118. var xhr = this.getXHR();
  119. xhr.open("post",this.uri,true);
  120. xhr.onreadystatechange = function() {
  121. if(xhr.readyState!=4)
  122. return;
  123. if(xhr.status==200) {
  124. if(id!=null) {
  125. var response = null;
  126. try {
  127. response = JSON.parse(xhr.responseText);
  128. }
  129. catch(e) {
  130. on_error({'type' : 'protocol', 'error' : 'invalid response'});
  131. return;
  132. }
  133. if(response.error != null) {
  134. on_error({'type': 'response', 'error' : response.error });
  135. }
  136. else {
  137. on_result(response.result);
  138. }
  139. }
  140. else {
  141. on_result();
  142. }
  143. }
  144. else {
  145. on_error( { 'type' : 'transport', 'error' : xhr.status } );
  146. }
  147. }
  148. this.runXHR(xhr,name,id,params);
  149. }
  150. ///
  151. /// Add new method, specify id = null for notification other valid id for function
  152. ///
  153. JsonRPC.prototype.addRPCMethod = function(method,id) {
  154. var call = function() {
  155. var args = new Array();
  156. for(var i=0;i<arguments.length;i++) {
  157. args[i]=arguments[i];
  158. }
  159. if(call.on_result != null) {
  160. this.asyncCall(method,id,args,call.on_result,call.on_error);
  161. }
  162. else
  163. return this.syncCall(method,id,args);
  164. };
  165. call.on_error = function(e) {
  166. throw Error(e.error);
  167. }
  168. call.on_result = null;
  169. this[method]=call;
  170. }