rjr 0.16.4 → 0.16.5
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.
- data/README.md +29 -16
- data/lib/rjr/common.rb +11 -1
- metadata +2 -2
data/README.md
CHANGED
@@ -4,7 +4,7 @@ Copyright (C) 2012-2013 Mo Morsi <mo@morsi.org>
|
|
4
4
|
|
5
5
|
RJR is made available under the Apache License, Version 2.0
|
6
6
|
|
7
|
-
RJR is an implementation of the
|
7
|
+
RJR is an implementation of the [JSON-RPC](http://en.wikipedia.org/wiki/JSON-RPC)
|
8
8
|
Version 2.0 Specification. It allows a developer to register custom JSON-RPC
|
9
9
|
method handlers which may be invoked simultaneously over a variety of transport
|
10
10
|
mechanisms.
|
@@ -14,6 +14,10 @@ Currently supported transports include:
|
|
14
14
|
|
15
15
|
Note some transports require additional dependencies, see rjr.gemspec for more info.
|
16
16
|
|
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
|
+
|
17
21
|
### Intro ###
|
18
22
|
To install rjr simply run:
|
19
23
|
gem install rjr
|
@@ -26,15 +30,18 @@ Source code is available via:
|
|
26
30
|
Simply require the transports which you would
|
27
31
|
like to use:
|
28
32
|
|
33
|
+
```ruby
|
29
34
|
require 'rjr/nodes/tcp'
|
30
35
|
require 'rjr/nodes/amqp'
|
31
36
|
require 'rjr/nodes/ws'
|
32
37
|
require 'rjr/nodes/web'
|
33
38
|
require 'rjr/nodes/local'
|
34
39
|
require 'rjr/nodes/multi'
|
40
|
+
```
|
35
41
|
|
36
42
|
server.rb:
|
37
43
|
|
44
|
+
```ruby
|
38
45
|
# listen for methods via amqp, websockets, http, and via local calls
|
39
46
|
amqp_node = RJR::Nodes::AMQP.new :node_id => 'server', :broker => 'localhost'
|
40
47
|
ws_node = RJR::Nodes::WS.new :node_id => 'server', :host => 'localhost', :port => 8080
|
@@ -51,10 +58,11 @@ server.rb:
|
|
51
58
|
# start the server and block
|
52
59
|
multi_node.listen
|
53
60
|
multi_node.join
|
54
|
-
|
61
|
+
```
|
55
62
|
|
56
63
|
amqp_client.rb:
|
57
64
|
|
65
|
+
```ruby
|
58
66
|
# invoke the method over amqp and return result
|
59
67
|
amqp_node = RJR::Nodes::AMQP.new :node_id => 'client', :broker => 'localhost'
|
60
68
|
puts amqp_node.invoke('server-queue', 'hello', 'world')
|
@@ -62,10 +70,11 @@ amqp_client.rb:
|
|
62
70
|
# send a notification via amqp,
|
63
71
|
# notifications immediately return and always return nil
|
64
72
|
amqp_node.notify('server-queue', 'hello', 'world')
|
65
|
-
|
73
|
+
```
|
66
74
|
|
67
75
|
ws_client.js:
|
68
76
|
|
77
|
+
```javascript
|
69
78
|
// use the js client to invoke the method via a websocket
|
70
79
|
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
|
71
80
|
<script type="text/javascript" src="site/json.js" />
|
@@ -83,12 +92,13 @@ ws_client.js:
|
|
83
92
|
};
|
84
93
|
node.open();
|
85
94
|
</script>
|
95
|
+
```
|
86
96
|
|
87
97
|
### Reference ###
|
88
98
|
|
89
|
-
The source repository can be found
|
99
|
+
The source repository can be found [here](https://github.com/movitto/rjr)
|
90
100
|
|
91
|
-
Online API documentation and examples can be found
|
101
|
+
Online API documentation and examples can be found [here](http://rubydoc.info/github/movitto/rjr)
|
92
102
|
|
93
103
|
Generate documentation via
|
94
104
|
|
@@ -106,28 +116,29 @@ are protected from concurrent access.
|
|
106
116
|
Various metadata fields are made available to json-rpc method handlers through
|
107
117
|
instance variables. These include:
|
108
118
|
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
* @rjr_handler
|
119
|
+
- @rjr_node
|
120
|
+
- @rjr_node_id
|
121
|
+
- @rjr_node_type
|
122
|
+
- @rjr_callback
|
123
|
+
- @rjr_headers
|
124
|
+
- @rjr_client_ip
|
125
|
+
- @rjr_client_port
|
126
|
+
- @rjr_method
|
127
|
+
- @rjr_method_args
|
128
|
+
- @rjr_handler
|
120
129
|
|
121
130
|
RJR implements a callback interface through which methods may be invoked on a client
|
122
131
|
after an initial server connection is established. Store and/or invoke @rjr_callback to make
|
123
132
|
use of this.
|
124
133
|
|
134
|
+
```ruby
|
125
135
|
node.dispatcher.handle("register_callback") do |*args|
|
126
136
|
$my_registry.invoke_me_later {
|
127
137
|
# rjr callback will already be setup to send messages to the correct client
|
128
138
|
@rjr_callback.invoke 'callback_method', 'with', 'custom', 'params'
|
129
139
|
}
|
130
140
|
end
|
141
|
+
```
|
131
142
|
|
132
143
|
RJR also permits arbitrary headers being set on JSON-RPC requests and responses. These
|
133
144
|
will be stored in the json send to/from nodes, at the same level/scope as the message
|
@@ -135,6 +146,7 @@ will be stored in the json send to/from nodes, at the same level/scope as the me
|
|
135
146
|
in their registered handlers to store additional metadata to extend the JSON-RPC protocol and
|
136
147
|
support any custom subsystems (an auth subsystem for example)
|
137
148
|
|
149
|
+
```ruby
|
138
150
|
node.dispatcher.handle("login") do |*args|
|
139
151
|
if $my_user_registry.find(:user => args.first, :pass => args.last)
|
140
152
|
@headers['session-id'] = $my_user_registry.create_session.id
|
@@ -147,6 +159,7 @@ support any custom subsystems (an auth subsystem for example)
|
|
147
159
|
end
|
148
160
|
# ...
|
149
161
|
end
|
162
|
+
```
|
150
163
|
|
151
164
|
Of course any custom headers set/used will only be of use to JSON-RPC nodes running
|
152
165
|
RJR as this is not standard JSON-RPC.
|
data/lib/rjr/common.rb
CHANGED
@@ -212,6 +212,12 @@ module RJR
|
|
212
212
|
if k == ::JSON.create_id &&
|
213
213
|
validate_json_class(v)
|
214
214
|
raise ArgumentError, "can't create json class #{v}"
|
215
|
+
elsif v.is_a?(Array)
|
216
|
+
v.each { |vi|
|
217
|
+
if vi.is_a?(Hash)
|
218
|
+
validate_json_hash(vi)
|
219
|
+
end
|
220
|
+
}
|
215
221
|
elsif v.is_a?(Hash)
|
216
222
|
validate_json_hash(v)
|
217
223
|
end
|
@@ -220,7 +226,11 @@ module RJR
|
|
220
226
|
|
221
227
|
def self.parse_json(js)
|
222
228
|
jp = ::JSON.parse js, :create_additions => false
|
223
|
-
|
229
|
+
if jp.is_a?(Array)
|
230
|
+
jp.each { |jpi| parse_json(jpi.to_json) }
|
231
|
+
elsif !jp.is_a?(Hash)
|
232
|
+
return
|
233
|
+
end
|
224
234
|
validate_json_hash(jp)
|
225
235
|
::JSON.parse js, :create_additions => true
|
226
236
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rjr
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.16.
|
4
|
+
version: 0.16.5
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-09-
|
12
|
+
date: 2013-09-27 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rspec
|