rjr 0.16.6 → 0.17.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/README.md +4 -6
- data/lib/rjr/dispatcher.rb +8 -4
- data/lib/rjr/nodes/tcp.rb +1 -1
- data/lib/rjr/nodes/ws.rb +3 -3
- data/lib/rjr/version.rb +3 -0
- data/site/index.html +2 -2
- data/site/jrw.js +251 -223
- data/specs/nodes/amqp_spec.rb +9 -3
- metadata +43 -31
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: df6830242efa865dde4af4008827688172011746
|
4
|
+
data.tar.gz: 33c559f6fa14957b7aa5929f3030ab4455e93b8e
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 240533c8a5aafa5980337b18fae10bf4f24a9e72e93ce6e88f42c82169ee81fbb5f850a5817a6ed1091f9ed62e96145e3b478f67b2122c15c39dbf13a29ff131
|
7
|
+
data.tar.gz: 56ef3f372c94eead71df0d5b534122a244c3602b4aab84c3c181d40711066c8ab7da303f3cb8f676531d6150e0f1c6be0c2836320bbda749a53f3451cdc7f5f0
|
data/README.md
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
## RJR - Ruby Json Rpc Library ##
|
2
|
+
[](https://travis-ci.org/movitto/rjr)
|
2
3
|
|
3
4
|
Copyright (C) 2012-2013 Mo Morsi <mo@morsi.org>
|
4
5
|
|
@@ -14,11 +15,9 @@ Currently supported transports include:
|
|
14
15
|
|
15
16
|
Note some transports require additional dependencies, see rjr.gemspec for more info.
|
16
17
|
|
17
|
-
**Note** currently there is an [issue](https://github.com/flori/json/issues/179) regarding compatability with the latest json gem.
|
18
|
-
Developers wishing to use RJR should use version 1.7.5 or lower (workaround is in progress).
|
19
|
-
|
20
|
-
|
21
18
|
### Intro ###
|
19
|
+
RJR is currently built ontop of [eventmachine](http://eventmachine.rubyforge.org/) and [json](https://github.com/flori/json), any dependencies of those are needed to run rjr.
|
20
|
+
|
22
21
|
To install rjr simply run:
|
23
22
|
gem install rjr
|
24
23
|
|
@@ -108,8 +107,7 @@ Also see examples and specs for detailed usage.
|
|
108
107
|
|
109
108
|
### Advanced ###
|
110
109
|
|
111
|
-
|
112
|
-
Upon being received requests are handed off to a thread pool to free up the reactor.
|
110
|
+
Upon receiving requests from eventmachine, rjr hands them off to a thread pool to free up the reactor.
|
113
111
|
It is up to the developer to ensure resources accessed in the method handlers
|
114
112
|
are protected from concurrent access.
|
115
113
|
|
data/lib/rjr/dispatcher.rb
CHANGED
@@ -189,11 +189,15 @@ class Dispatcher
|
|
189
189
|
|
190
190
|
# RJR::Dispatcher intializer
|
191
191
|
def initialize
|
192
|
-
|
193
|
-
@environments = Hash.new()
|
194
|
-
|
192
|
+
clear!
|
195
193
|
@requests_lock = Mutex.new
|
196
|
-
|
194
|
+
end
|
195
|
+
|
196
|
+
# Return dispatcher to its initial state
|
197
|
+
def clear!
|
198
|
+
@handlers = {}
|
199
|
+
@environments = {}
|
200
|
+
@requests = []
|
197
201
|
end
|
198
202
|
|
199
203
|
# Loads module from fs and adds handlers defined there
|
data/lib/rjr/nodes/tcp.rb
CHANGED
data/lib/rjr/nodes/ws.rb
CHANGED
@@ -101,7 +101,7 @@ class WS < RJR::Node
|
|
101
101
|
#
|
102
102
|
# Implementation of {RJR::Node#send_msg}
|
103
103
|
def send_msg(data, ws)
|
104
|
-
ws.send(data)
|
104
|
+
@@em.schedule { ws.send(data) }
|
105
105
|
end
|
106
106
|
|
107
107
|
# Instruct Node to start listening for and dispatching rpc requests
|
@@ -137,7 +137,7 @@ class WS < RJR::Node
|
|
137
137
|
|
138
138
|
@@em.schedule {
|
139
139
|
init_client(uri) do |c|
|
140
|
-
c.stream { |msg| handle_message(msg, c) }
|
140
|
+
c.stream { |msg| handle_message(msg.data, c) }
|
141
141
|
|
142
142
|
c.send_msg message.to_s
|
143
143
|
end
|
@@ -171,7 +171,7 @@ class WS < RJR::Node
|
|
171
171
|
:headers => @message_headers
|
172
172
|
@@em.schedule {
|
173
173
|
init_client(uri) do |c|
|
174
|
-
c.stream { |msg| handle_message(msg, c) }
|
174
|
+
c.stream { |msg| handle_message(msg.data, c) }
|
175
175
|
|
176
176
|
c.send_msg message.to_s
|
177
177
|
|
data/lib/rjr/version.rb
ADDED
data/site/index.html
CHANGED
@@ -20,7 +20,7 @@
|
|
20
20
|
<script type="text/javascript" src="json.js"></script>
|
21
21
|
<script type="text/javascript" src="jrw.js"></script>
|
22
22
|
<script type="text/javascript">
|
23
|
-
var ws_node = new
|
23
|
+
var ws_node = new RJR.WsNode('127.0.0.1', '8080');
|
24
24
|
ws_node.onopen = function(){
|
25
25
|
ws_node.invoke('stress', 'ws1', function(res){
|
26
26
|
alert(res.result);
|
@@ -33,7 +33,7 @@
|
|
33
33
|
};
|
34
34
|
ws_node.open();
|
35
35
|
|
36
|
-
var www_node = new
|
36
|
+
var www_node = new RJR.HttpNode('http://localhost/rjr');
|
37
37
|
www_node.invoke('stress', 'http1', function(res){
|
38
38
|
alert(res.result);
|
39
39
|
})
|
data/site/jrw.js
CHANGED
@@ -1,302 +1,330 @@
|
|
1
|
-
/*
|
1
|
+
/* JSON-RPC over HTTP and WebSockets
|
2
2
|
*
|
3
|
-
*
|
4
|
-
*
|
3
|
+
* Copyright (C) 2013 Mohammed Morsi <mo@morsi.org>
|
4
|
+
* Licensed under the Apache License, Version 2.0
|
5
5
|
*/
|
6
6
|
|
7
|
-
|
8
|
-
|
9
|
-
|
7
|
+
var RJR = { REVISION: '1' };
|
8
|
+
|
9
|
+
// Generate a new ascii string of length 4
|
10
|
+
RJR.S4 = function() {
|
10
11
|
return (((1+Math.random())*0x10000)|0).toString(16).substring(1);
|
11
|
-
}
|
12
|
-
|
13
|
-
|
12
|
+
};
|
13
|
+
|
14
|
+
// Generate a new uuid
|
15
|
+
RJR.guid = function() {
|
16
|
+
return (RJR.S4()+RJR.S4()+"-"+RJR.S4()+"-"+RJR.S4()+"-"+RJR.S4()+"-"+RJR.S4()+RJR.S4()+RJR.S4());
|
17
|
+
};
|
18
|
+
|
19
|
+
// Return bool indicating if specified data is a jsonrpc object
|
20
|
+
RJR.is_jr_object = function(obj){
|
21
|
+
return obj && obj['json_class'];
|
14
22
|
}
|
15
23
|
|
16
|
-
|
17
|
-
|
24
|
+
// Return bool indicating if specified data is an array
|
25
|
+
RJR.is_array = function(obj){
|
26
|
+
return obj && typeof(obj) == 'object' && obj.length != undefined;
|
27
|
+
}
|
18
28
|
|
19
29
|
// Encapsulates a json-rpc message
|
20
|
-
function
|
21
|
-
|
30
|
+
RJR.JRMessage = function(){
|
31
|
+
// standard jsonrpc message fields
|
32
|
+
this.id = null;
|
22
33
|
this.rpc_method = null;
|
23
|
-
this.
|
24
|
-
|
25
|
-
this.
|
26
|
-
this.json = null;
|
27
|
-
|
28
|
-
this.error = null;
|
29
|
-
this.result = null;
|
34
|
+
this.params = [];
|
35
|
+
this.error = null;
|
36
|
+
this.result = null;
|
30
37
|
|
38
|
+
// extra data used locally
|
31
39
|
this.onresponse = null;
|
32
|
-
this.
|
40
|
+
this.headers = {};
|
41
|
+
};
|
33
42
|
|
34
|
-
|
35
|
-
|
36
|
-
|
43
|
+
RJR.JRMessage.prototype = {
|
44
|
+
// Convert message to json string
|
45
|
+
to_json : function(){
|
46
|
+
var params = RJR.JRMessage.convert_params(this.params);
|
47
|
+
var msg = {jsonrpc: '2.0',
|
48
|
+
method: this.rpc_method,
|
49
|
+
params: params,
|
50
|
+
id: this.id};
|
51
|
+
for(var h in this.headers)
|
52
|
+
msg[h] = this.headers[h];
|
53
|
+
return $.toJSON(msg);
|
54
|
+
},
|
55
|
+
|
56
|
+
// Invoke response handler if registered
|
57
|
+
handle_response : function(res){
|
58
|
+
if(this.onresponse) this.onresponse(res);
|
37
59
|
}
|
60
|
+
};
|
38
61
|
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
62
|
+
// Convert js params to json params
|
63
|
+
RJR.JRMessage.convert_params = function(params){
|
64
|
+
var jrparams = [];
|
65
|
+
for(var p = 0; p < params.length; p++){
|
66
|
+
var param = params[p];
|
67
|
+
if(RJR.is_jr_object(param)){
|
68
|
+
// FIXME need to check each param property as well (converting if necessary)
|
69
|
+
var json_class = param['json_class'];
|
70
|
+
delete param['json_class'];
|
71
|
+
jrparams.push({json_class: json_class,
|
72
|
+
data : param});
|
73
|
+
}else if(RJR.is_array(param))
|
74
|
+
jrparams.push(RJR.JRMessage.convert_params(param));
|
75
|
+
else
|
76
|
+
jrparams.push(param);
|
43
77
|
}
|
78
|
+
return jrparams;
|
44
79
|
}
|
45
80
|
|
46
|
-
//
|
47
|
-
JRMessage.
|
48
|
-
var
|
49
|
-
|
50
|
-
msg
|
51
|
-
msg.
|
52
|
-
msg.
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
//
|
64
|
-
// node_id and headers will be set on request message before it
|
65
|
-
// is returned
|
66
|
-
JRMessage.pretty_request = function(args, node_id, headers){
|
67
|
-
// create request message
|
68
|
-
var rpc_method = args[0];
|
69
|
-
var params = [];
|
70
|
-
var cb = null;
|
71
|
-
for(a = 1; a < args.length; a++){
|
72
|
-
if(a == args.length - 1 && typeof args[a] === 'function')
|
73
|
-
cb = args[a];
|
81
|
+
// Parse a json string to a JRMessage
|
82
|
+
RJR.JRMessage.parse = function(json){
|
83
|
+
var data = $.evalJSON(json);
|
84
|
+
|
85
|
+
var msg = new RJR.JRMessage();
|
86
|
+
msg.id = data['id'];
|
87
|
+
msg.rpc_method = data['method'];
|
88
|
+
msg.error = data['error'];
|
89
|
+
|
90
|
+
var params = data['params'];
|
91
|
+
if(params){
|
92
|
+
for(var d=0; d<params.length; d++){
|
93
|
+
var param = params[d];
|
94
|
+
if(RJR.is_jr_object(param))
|
95
|
+
msg.params.push(RJR.JRMessage.parse_obj(param));
|
96
|
+
else if(RJR.is_array(param))
|
97
|
+
msg.params.push(RJR.JRMessage.parse_array(param));
|
74
98
|
else
|
75
|
-
params.push(
|
99
|
+
msg.params.push(param);
|
100
|
+
}
|
76
101
|
}
|
77
|
-
var req = JRMessage.new_request(rpc_method, params);
|
78
|
-
if(node_id) req.data['node_id'] = node_id;
|
79
|
-
for(var header in headers)
|
80
|
-
req.data[header] = headers[header];
|
81
102
|
|
82
|
-
|
83
|
-
if(
|
103
|
+
var result = data['result'];
|
104
|
+
if(result){
|
105
|
+
if(RJR.is_jr_object(result))
|
106
|
+
msg.result = RJR.JRMessage.parse_obj(result);
|
107
|
+
else if(RJR.is_array(result))
|
108
|
+
msg.result = RJR.JRMessage.parse_array(result);
|
109
|
+
else
|
110
|
+
msg.result = result;
|
111
|
+
}
|
84
112
|
|
85
|
-
return
|
86
|
-
}
|
113
|
+
return msg;
|
114
|
+
};
|
87
115
|
|
88
|
-
// Parse
|
89
|
-
JRMessage.
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
else if(JRObject.is_jrobject_array(msg.params[p]))
|
102
|
-
msg.params[p] = JRObject.from_json_array(msg.params[p]);
|
103
|
-
}
|
116
|
+
// Parse a json object into a js object
|
117
|
+
RJR.JRMessage.parse_obj = function(obj){
|
118
|
+
// TODO mechanism to lookup class and auto
|
119
|
+
// instantiate instead of generic js object
|
120
|
+
var result = {json_class : obj['json_class']};
|
121
|
+
for(var p in obj['data']){
|
122
|
+
var property = obj['data'][p];
|
123
|
+
if(RJR.is_jr_object(property))
|
124
|
+
result[p] = RJR.JRMessage.parse_obj(property);
|
125
|
+
else if(RJR.is_array(obj[p]))
|
126
|
+
result[p] = RJR.JRMessage.parse_array(property);
|
127
|
+
else
|
128
|
+
result[p] = property;
|
104
129
|
}
|
105
|
-
|
106
|
-
msg.result = msg.data['result'];
|
107
|
-
if(msg.result && JRObject.is_jrobject(msg.result))
|
108
|
-
msg.result = JRObject.from_json(msg.result);
|
109
|
-
else if(JRObject.is_jrobject_array(msg.result))
|
110
|
-
msg.result = JRObject.from_json_array(msg.result);
|
111
|
-
return msg;
|
130
|
+
return result;
|
112
131
|
}
|
113
132
|
|
114
|
-
|
115
|
-
//
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
return {json_class: this.type, data: data };
|
130
|
-
};
|
131
|
-
};
|
133
|
+
// Parse an array, potentially containing json data,
|
134
|
+
// into a js array
|
135
|
+
RJR.JRMessage.parse_array = function(array){
|
136
|
+
var result = [];
|
137
|
+
for(var a=0; a<array.length; a++){
|
138
|
+
var item = array[a];
|
139
|
+
if(RJR.is_jr_object(item))
|
140
|
+
result.push(RJR.JRMessage.parse_obj(item));
|
141
|
+
else if(RJR.is_array(item))
|
142
|
+
result.push(RJR.JRMessage.parse_array(item));
|
143
|
+
else
|
144
|
+
result.push(item);
|
145
|
+
}
|
146
|
+
return result;
|
147
|
+
}
|
132
148
|
|
133
|
-
//
|
134
|
-
|
135
|
-
|
149
|
+
// Create new request message to send
|
150
|
+
RJR.JRMessage.new_request = function(rpc_method, params){
|
151
|
+
var msg = new RJR.JRMessage();
|
152
|
+
msg.id = RJR.guid();
|
153
|
+
msg.rpc_method = rpc_method;
|
154
|
+
msg.params = params;
|
155
|
+
return msg;
|
136
156
|
};
|
137
157
|
|
138
|
-
//
|
139
|
-
|
140
|
-
|
141
|
-
|
158
|
+
// Helper method to convert method arguments to:
|
159
|
+
// - rpc_method
|
160
|
+
// - parameter list
|
161
|
+
// - callback (if last argument is a function, else null)
|
162
|
+
RJR.JRMessage.prepare_args = function(args){
|
163
|
+
var rpc_method = args[0];
|
164
|
+
var cb = null;
|
165
|
+
if(typeof(args[args.length-1]) === 'function')
|
166
|
+
cb = args[args.length-1];
|
142
167
|
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
if(JRObject.is_jrobject(obj[p]))
|
149
|
-
obj[p] = JRObject.from_json(obj[p]);
|
150
|
-
else if(JRObject.is_jrobject_array(obj[p])){
|
151
|
-
obj[p] = JRObject.from_json_array(obj[p]);
|
152
|
-
}
|
168
|
+
var params = [];
|
169
|
+
for(var a = 1; a < args.length; a++){
|
170
|
+
var arg = args[a];
|
171
|
+
if(typeof(arg) !== 'function')
|
172
|
+
params.push(arg);
|
153
173
|
}
|
154
|
-
return obj;
|
155
|
-
};
|
156
174
|
|
157
|
-
|
158
|
-
JRObject.from_json_array = function(json){
|
159
|
-
var objs = [];
|
160
|
-
for(var i in json)
|
161
|
-
if(JRObject.is_jrobject(json[i]))
|
162
|
-
objs[i] = JRObject.from_json(json[i]);
|
163
|
-
return objs;
|
175
|
+
return [rpc_method, params, cb];
|
164
176
|
};
|
165
177
|
|
166
|
-
|
167
|
-
|
178
|
+
// Helper to prepare a request for the specified node
|
179
|
+
RJR.JRMessage.request_for_node = function(node, args){
|
180
|
+
var preq = RJR.JRMessage.prepare_args(args);
|
181
|
+
var req = RJR.JRMessage.new_request(preq[0], preq[1]);
|
182
|
+
req.onresponse = preq[2];
|
183
|
+
req.headers = node.headers;
|
184
|
+
req.headers['node_id'] = node.node_id;
|
185
|
+
return req;
|
186
|
+
};
|
168
187
|
|
169
188
|
// Main json-rpc client websocket interface
|
170
|
-
|
171
|
-
|
189
|
+
RJR.WsNode = function(host, port){
|
190
|
+
this.host = host;
|
191
|
+
this.port = port;
|
172
192
|
this.opening = false;
|
173
193
|
this.opened = false;
|
174
194
|
this.node_id = null;
|
175
195
|
this.headers = {};
|
176
196
|
this.messages = {};
|
197
|
+
};
|
177
198
|
|
199
|
+
RJR.WsNode.prototype = {
|
178
200
|
// Open socket connection
|
179
|
-
|
201
|
+
open : function(){
|
202
|
+
var node = this;
|
180
203
|
if(this.opening) return;
|
181
204
|
this.opening = true;
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
// clients may user this to register additional handlers to be invoked
|
208
|
-
// upon request responses
|
209
|
-
if(node.message_received)
|
210
|
-
node.message_received(msg);
|
211
|
-
};
|
212
|
-
|
213
|
-
node.socket.onerror = function(e){
|
214
|
-
if(node.onerror)
|
215
|
-
node.onerror(e);
|
205
|
+
this.socket = new WebSocket("ws://" + this.host + ":" + this.port);
|
206
|
+
this.socket.onclose = function(){ node._socket_close(); };
|
207
|
+
this.socket.onmessage = function(evnt){ node._socket_msg(evnt); };
|
208
|
+
this.socket.onerror = function(err){ node._socket_err(err); };
|
209
|
+
this.socket.onopen = function(){ node._socket_open(); };
|
210
|
+
|
211
|
+
},
|
212
|
+
|
213
|
+
_socket_close : function(){
|
214
|
+
if(this.onclose) this.onclose();
|
215
|
+
},
|
216
|
+
|
217
|
+
_socket_msg : function(evnt){
|
218
|
+
var msg = RJR.JRMessage.parse(evnt.data);
|
219
|
+
|
220
|
+
// match response w/ outstanding request
|
221
|
+
if(msg.id){
|
222
|
+
var req = this.messages[msg.id];
|
223
|
+
delete this.messages[msg.id];
|
224
|
+
req.handle_response(msg)
|
225
|
+
|
226
|
+
// if err msg, run this.onerror
|
227
|
+
if(msg.error)
|
228
|
+
if(this.onerror)
|
229
|
+
this.onerror(msg)
|
216
230
|
}
|
217
231
|
|
218
|
-
|
219
|
-
|
220
|
-
|
232
|
+
// relying on clients to handle notifications via message_received
|
233
|
+
// TODO add notification (and request?) handler support here
|
234
|
+
// clients may user this to register additional handlers to be invoked
|
235
|
+
// upon request responses
|
236
|
+
if(this.message_received)
|
237
|
+
this.message_received(msg);
|
238
|
+
},
|
239
|
+
|
240
|
+
_socket_err : function(e){
|
241
|
+
if(this.onerror)
|
242
|
+
this.onerror(e);
|
243
|
+
},
|
244
|
+
|
245
|
+
_socket_open : function(){
|
246
|
+
this.opened = true;
|
247
|
+
this.opening = false;
|
221
248
|
|
222
|
-
|
223
|
-
|
224
|
-
|
249
|
+
// send queued messages
|
250
|
+
for(var m in this.messages)
|
251
|
+
this.socket.send(this.messages[m].to_json());
|
225
252
|
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
};
|
253
|
+
// invoke client callback
|
254
|
+
if(this.onopen)
|
255
|
+
this.onopen();
|
256
|
+
},
|
231
257
|
|
232
258
|
// Close socket connection
|
233
|
-
|
259
|
+
close : function(){
|
234
260
|
this.socket.close();
|
235
|
-
}
|
261
|
+
},
|
236
262
|
|
237
263
|
// Invoke request on socket, may be invoked before or after socket is opened.
|
238
264
|
//
|
239
265
|
// Pass in the rpc method, arguments to invoke method with, and optional callback
|
240
266
|
// to be invoked upon received response.
|
241
|
-
|
242
|
-
var req = JRMessage.
|
267
|
+
invoke : function(){
|
268
|
+
var req = RJR.JRMessage.request_for_node(this, arguments);
|
243
269
|
|
244
270
|
// store requests for later retrieval
|
245
271
|
this.messages[req.id] = req;
|
246
272
|
|
247
|
-
if(
|
273
|
+
if(this.opened)
|
248
274
|
this.socket.send(req.to_json());
|
249
275
|
|
250
276
|
return req;
|
251
|
-
}
|
277
|
+
}
|
252
278
|
};
|
253
279
|
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
// Main json-rpc www interface
|
258
|
-
function WebNode (uri){
|
259
|
-
var node = this;
|
280
|
+
// Main json-rpc http interface
|
281
|
+
RJR.HttpNode = function(uri){
|
282
|
+
this.uri = uri;
|
260
283
|
this.node_id = null;
|
261
284
|
this.headers = {};
|
285
|
+
};
|
262
286
|
|
287
|
+
RJR.HttpNode.prototype = {
|
263
288
|
// Invoke request via http
|
264
289
|
//
|
265
290
|
// Pass in the rpc method, arguments to invoke method with, and optional callback
|
266
291
|
// to be invoked upon received response.
|
267
|
-
|
268
|
-
var req = JRMessage.
|
292
|
+
invoke : function(){
|
293
|
+
var req = RJR.JRMessage.request_for_node(this, arguments);
|
269
294
|
|
295
|
+
var node = this;
|
270
296
|
$.ajax({type: 'POST',
|
271
|
-
url: uri,
|
297
|
+
url: this.uri,
|
272
298
|
data: req.to_json(),
|
273
299
|
dataType: 'text', // using text so we can parse json ourselves
|
274
|
-
|
275
|
-
|
276
|
-
var msg = JRMessage.from_msg(data);
|
277
|
-
// clients may register additional callbacks
|
278
|
-
// to handle web node responses
|
279
|
-
if(node.message_received)
|
280
|
-
node.message_received(msg);
|
281
|
-
|
282
|
-
req.handle_response(msg)
|
283
|
-
|
284
|
-
// if err msg, run node.onerror
|
285
|
-
if(msg.error)
|
286
|
-
if(node.onerror)
|
287
|
-
node.onerror(msg);
|
288
|
-
},
|
289
|
-
|
290
|
-
error: function(jqXHR, textStatus, errorThrown){
|
291
|
-
var err = { 'error' : {'code' : jqXHR.status,
|
292
|
-
'message' : textStatus,
|
293
|
-
'class' : errorThrown } };
|
294
|
-
if(node.onerror)
|
295
|
-
node.onerror(err);
|
296
|
-
|
297
|
-
req.handle_response(err)
|
298
|
-
}});
|
300
|
+
success: function(data) { node._http_success(data, req); },
|
301
|
+
error: function(hr, st, et) { node._http_err(hr, st, et, req); }});
|
299
302
|
|
300
303
|
return req;
|
301
|
-
}
|
304
|
+
},
|
305
|
+
|
306
|
+
_http_success : function(data, req){
|
307
|
+
var msg = RJR.JRMessage.parse(data);
|
308
|
+
// clients may register additional callbacks
|
309
|
+
// to handle web node responses
|
310
|
+
if(this.message_received)
|
311
|
+
this.message_received(msg);
|
312
|
+
|
313
|
+
req.handle_response(msg)
|
314
|
+
|
315
|
+
// if err msg, run this.onerror
|
316
|
+
if(msg.error)
|
317
|
+
if(this.onerror)
|
318
|
+
this.onerror(msg);
|
319
|
+
},
|
320
|
+
|
321
|
+
_http_err : function(jqXHR, textStatus, errorThrown, req){
|
322
|
+
var err = { 'error' : {'code' : jqXHR.status,
|
323
|
+
'message' : textStatus,
|
324
|
+
'class' : errorThrown } };
|
325
|
+
if(this.onerror)
|
326
|
+
this.onerror(err);
|
327
|
+
|
328
|
+
req.handle_response(err)
|
329
|
+
}
|
302
330
|
};
|
data/specs/nodes/amqp_spec.rb
CHANGED
@@ -7,6 +7,12 @@ puts "Missing AMQP node dependencies, skipping amqp tests"
|
|
7
7
|
else
|
8
8
|
# TODO stub out calls to external rabbitmq server
|
9
9
|
|
10
|
+
# helper to stop em
|
11
|
+
def stop_node(node)
|
12
|
+
Thread.new { ::AMQP.stop { node.halt } }
|
13
|
+
node.join
|
14
|
+
end
|
15
|
+
|
10
16
|
module RJR::Nodes
|
11
17
|
describe AMQP do
|
12
18
|
describe "#send_msg" do
|
@@ -33,7 +39,7 @@ module RJR::Nodes
|
|
33
39
|
:broker => 'localhost').invoke 'server-queue',
|
34
40
|
'test',
|
35
41
|
'myparam'
|
36
|
-
node
|
42
|
+
stop_node(node)
|
37
43
|
invoked.should be_true
|
38
44
|
ci.should be_nil
|
39
45
|
cp.should be_nil
|
@@ -55,7 +61,7 @@ module RJR::Nodes
|
|
55
61
|
client = AMQP.new :node_id => 'client', :broker => 'localhost'
|
56
62
|
res = client.invoke 'server-queue', 'test', 'myparam'
|
57
63
|
|
58
|
-
|
64
|
+
stop_node(client)
|
59
65
|
res.should == 'retval'
|
60
66
|
end
|
61
67
|
end
|
@@ -71,7 +77,7 @@ module RJR::Nodes
|
|
71
77
|
client = AMQP.new :node_id => 'client', :broker => 'localhost'
|
72
78
|
res = client.notify 'server-queue', 'test', 'myparam'
|
73
79
|
|
74
|
-
server
|
80
|
+
stop_node(server)
|
75
81
|
res.should == nil
|
76
82
|
end
|
77
83
|
end
|
metadata
CHANGED
@@ -1,62 +1,55 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rjr
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
5
|
-
prerelease:
|
4
|
+
version: 0.17.1
|
6
5
|
platform: ruby
|
7
6
|
authors:
|
8
|
-
-
|
7
|
+
- Mo Morsi
|
9
8
|
autorequire:
|
10
9
|
bindir: bin
|
11
10
|
cert_chain: []
|
12
|
-
date: 2013-
|
11
|
+
date: 2013-12-17 00:00:00.000000000 Z
|
13
12
|
dependencies:
|
14
13
|
- !ruby/object:Gem::Dependency
|
15
14
|
name: rspec
|
16
15
|
requirement: !ruby/object:Gem::Requirement
|
17
|
-
none: false
|
18
16
|
requirements:
|
19
|
-
- -
|
17
|
+
- - '>='
|
20
18
|
- !ruby/object:Gem::Version
|
21
19
|
version: 2.0.0
|
22
20
|
type: :development
|
23
21
|
prerelease: false
|
24
22
|
version_requirements: !ruby/object:Gem::Requirement
|
25
|
-
none: false
|
26
23
|
requirements:
|
27
|
-
- -
|
24
|
+
- - '>='
|
28
25
|
- !ruby/object:Gem::Version
|
29
26
|
version: 2.0.0
|
30
27
|
- !ruby/object:Gem::Dependency
|
31
28
|
name: eventmachine
|
32
29
|
requirement: !ruby/object:Gem::Requirement
|
33
|
-
none: false
|
34
30
|
requirements:
|
35
|
-
- -
|
31
|
+
- - '>='
|
36
32
|
- !ruby/object:Gem::Version
|
37
33
|
version: '0'
|
38
34
|
type: :runtime
|
39
35
|
prerelease: false
|
40
36
|
version_requirements: !ruby/object:Gem::Requirement
|
41
|
-
none: false
|
42
37
|
requirements:
|
43
|
-
- -
|
38
|
+
- - '>='
|
44
39
|
- !ruby/object:Gem::Version
|
45
40
|
version: '0'
|
46
41
|
- !ruby/object:Gem::Dependency
|
47
42
|
name: json
|
48
43
|
requirement: !ruby/object:Gem::Requirement
|
49
|
-
none: false
|
50
44
|
requirements:
|
51
|
-
- -
|
45
|
+
- - '>='
|
52
46
|
- !ruby/object:Gem::Version
|
53
47
|
version: 1.7.6
|
54
48
|
type: :runtime
|
55
49
|
prerelease: false
|
56
50
|
version_requirements: !ruby/object:Gem::Requirement
|
57
|
-
none: false
|
58
51
|
requirements:
|
59
|
-
- -
|
52
|
+
- - '>='
|
60
53
|
- !ruby/object:Gem::Version
|
61
54
|
version: 1.7.6
|
62
55
|
description: Ruby Json Rpc library
|
@@ -80,6 +73,7 @@ files:
|
|
80
73
|
- lib/rjr/em_adapter.rb
|
81
74
|
- lib/rjr/errors.rb
|
82
75
|
- lib/rjr/inspect.rb
|
76
|
+
- lib/rjr/version.rb
|
83
77
|
- lib/rjr/node.rb
|
84
78
|
- lib/rjr/common.rb
|
85
79
|
- lib/rjr/thread_pool.rb
|
@@ -96,6 +90,13 @@ files:
|
|
96
90
|
- lib/rjr/nodes/missing.rb
|
97
91
|
- lib/rjr/nodes/multi.rb
|
98
92
|
- lib/rjr/dispatcher.rb
|
93
|
+
- site/index.html
|
94
|
+
- site/jquery-latest.js
|
95
|
+
- site/json.js
|
96
|
+
- site/jrw.js
|
97
|
+
- LICENSE
|
98
|
+
- Rakefile
|
99
|
+
- README.md
|
99
100
|
- specs/dispatcher_spec.rb
|
100
101
|
- specs/node_spec.rb
|
101
102
|
- specs/nodes/multi_spec.rb
|
@@ -109,33 +110,31 @@ files:
|
|
109
110
|
- specs/thread_pool_spec.rb
|
110
111
|
- specs/message_spec.rb
|
111
112
|
- specs/em_adapter_spec.rb
|
112
|
-
- site/index.html
|
113
|
-
- site/jquery-latest.js
|
114
|
-
- site/json.js
|
115
|
-
- site/jrw.js
|
116
|
-
- LICENSE
|
117
|
-
- Rakefile
|
118
|
-
- README.md
|
119
113
|
- bin/rjr-server
|
120
114
|
- bin/rjr-client
|
121
115
|
- bin/rjr-client-launcher
|
122
116
|
homepage: http://github.com/movitto/rjr
|
123
117
|
licenses:
|
124
118
|
- Apache 2.0
|
125
|
-
|
119
|
+
metadata: {}
|
120
|
+
post_install_message: |-
|
121
|
+
---
|
122
|
+
RJR - Optional Transport Requirements
|
123
|
+
The amqp gem and a running rabbitmq server is needed to use the amqp node
|
124
|
+
The eventmachine_httpserver and em-http-request gems are needed to use the web node
|
125
|
+
The em-websocket and em-websocket-client gems are needed to use the web socket node
|
126
|
+
---
|
126
127
|
rdoc_options: []
|
127
128
|
require_paths:
|
128
129
|
- lib
|
129
130
|
required_ruby_version: !ruby/object:Gem::Requirement
|
130
|
-
none: false
|
131
131
|
requirements:
|
132
|
-
- -
|
132
|
+
- - '>='
|
133
133
|
- !ruby/object:Gem::Version
|
134
134
|
version: 1.8.1
|
135
135
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
136
|
-
none: false
|
137
136
|
requirements:
|
138
|
-
- -
|
137
|
+
- - '>='
|
139
138
|
- !ruby/object:Gem::Version
|
140
139
|
version: 1.3.3
|
141
140
|
requirements:
|
@@ -143,9 +142,22 @@ requirements:
|
|
143
142
|
- The eventmachine_httpserver and em-http-request gems are needed to use the web node
|
144
143
|
- The em-websocket and em-websocket-client gems are needed to use the web socket node
|
145
144
|
rubyforge_project:
|
146
|
-
rubygems_version:
|
145
|
+
rubygems_version: 2.0.11
|
147
146
|
signing_key:
|
148
|
-
specification_version:
|
147
|
+
specification_version: 4
|
149
148
|
summary: JSON RPC server and client library over amqp, websockets, http, etc
|
150
|
-
test_files:
|
149
|
+
test_files:
|
150
|
+
- specs/dispatcher_spec.rb
|
151
|
+
- specs/node_spec.rb
|
152
|
+
- specs/nodes/multi_spec.rb
|
153
|
+
- specs/nodes/tcp_spec.rb
|
154
|
+
- specs/nodes/web_spec.rb
|
155
|
+
- specs/nodes/local_spec.rb
|
156
|
+
- specs/nodes/amqp_spec.rb
|
157
|
+
- specs/nodes/ws_spec.rb
|
158
|
+
- specs/nodes/easy_spec.rb
|
159
|
+
- specs/inspect_spec.rb
|
160
|
+
- specs/thread_pool_spec.rb
|
161
|
+
- specs/message_spec.rb
|
162
|
+
- specs/em_adapter_spec.rb
|
151
163
|
has_rdoc:
|