rjr 0.16.6 → 0.17.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
+
[![Build Status](https://travis-ci.org/movitto/rjr.png?branch=dep-fixes)](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:
|