rjr 0.12.2 → 0.15.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.
- data/README.md +49 -36
- data/Rakefile +2 -0
- data/bin/rjr-client +11 -9
- data/bin/rjr-server +12 -10
- data/examples/amqp.rb +29 -0
- data/examples/client.rb +32 -0
- data/examples/complete.rb +36 -0
- data/examples/local.rb +29 -0
- data/examples/server.rb +26 -0
- data/examples/tcp.rb +29 -0
- data/examples/web.rb +22 -0
- data/examples/ws.rb +29 -0
- data/lib/rjr/common.rb +7 -12
- data/lib/rjr/dispatcher.rb +171 -239
- data/lib/rjr/em_adapter.rb +33 -66
- data/lib/rjr/message.rb +43 -12
- data/lib/rjr/node.rb +197 -103
- data/lib/rjr/nodes/amqp.rb +216 -0
- data/lib/rjr/nodes/easy.rb +159 -0
- data/lib/rjr/nodes/local.rb +118 -0
- data/lib/rjr/{missing_node.rb → nodes/missing.rb} +4 -2
- data/lib/rjr/nodes/multi.rb +79 -0
- data/lib/rjr/nodes/tcp.rb +211 -0
- data/lib/rjr/nodes/web.rb +197 -0
- data/lib/rjr/nodes/ws.rb +187 -0
- data/lib/rjr/stats.rb +70 -0
- data/lib/rjr/thread_pool.rb +178 -123
- data/site/index.html +45 -0
- data/site/jquery-latest.js +9404 -0
- data/site/jrw.js +297 -0
- data/site/json.js +199 -0
- data/specs/dispatcher_spec.rb +244 -198
- data/specs/em_adapter_spec.rb +52 -80
- data/specs/message_spec.rb +223 -197
- data/specs/node_spec.rb +67 -163
- data/specs/nodes/amqp_spec.rb +82 -0
- data/specs/nodes/easy_spec.rb +13 -0
- data/specs/nodes/local_spec.rb +72 -0
- data/specs/nodes/multi_spec.rb +65 -0
- data/specs/nodes/tcp_spec.rb +75 -0
- data/specs/nodes/web_spec.rb +77 -0
- data/specs/nodes/ws_spec.rb +78 -0
- data/specs/stats_spec.rb +59 -0
- data/specs/thread_pool_spec.rb +44 -35
- metadata +40 -30
- data/lib/rjr/amqp_node.rb +0 -330
- data/lib/rjr/inspect.rb +0 -65
- data/lib/rjr/local_node.rb +0 -150
- data/lib/rjr/multi_node.rb +0 -65
- data/lib/rjr/tcp_node.rb +0 -323
- data/lib/rjr/thread_pool2.rb +0 -272
- data/lib/rjr/util.rb +0 -104
- data/lib/rjr/web_node.rb +0 -266
- data/lib/rjr/ws_node.rb +0 -289
- data/lib/rjr.rb +0 -16
- data/specs/amqp_node_spec.rb +0 -31
- data/specs/inspect_spec.rb +0 -60
- data/specs/local_node_spec.rb +0 -43
- data/specs/multi_node_spec.rb +0 -45
- data/specs/tcp_node_spec.rb +0 -33
- data/specs/util_spec.rb +0 -46
- data/specs/web_node_spec.rb +0 -32
- data/specs/ws_node_spec.rb +0 -32
- /data/lib/rjr/{tcp_node2.rb → nodes/tcp2.rb} +0 -0
- /data/lib/rjr/{udp_node.rb → nodes/udp.rb} +0 -0
data/README.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
## RJR - Ruby Json Rpc Library ##
|
2
2
|
|
3
|
-
Copyright (C) 2012 Mo Morsi <mo@morsi.org>
|
3
|
+
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
|
|
@@ -10,7 +10,9 @@ method handlers which may be invoked simultaneously over a variety of transport
|
|
10
10
|
mechanisms.
|
11
11
|
|
12
12
|
Currently supported transports include:
|
13
|
-
tcp, amqp, http (post), websockets, local method calls, (
|
13
|
+
tcp, amqp, http (post), websockets, local method calls, (others coming soon)
|
14
|
+
|
15
|
+
Note some transports require additional dependencies, see rjr.gemspec for more info.
|
14
16
|
|
15
17
|
### Intro ###
|
16
18
|
To install rjr simply run:
|
@@ -21,36 +23,45 @@ Source code is available via:
|
|
21
23
|
|
22
24
|
### Using ###
|
23
25
|
|
24
|
-
Simply require
|
26
|
+
Simply require the transports which you would
|
27
|
+
like to use:
|
25
28
|
|
26
|
-
require '
|
27
|
-
require 'rjr'
|
29
|
+
require 'rjr/nodes/tcp'
|
30
|
+
require 'rjr/nodes/amqp'
|
31
|
+
require 'rjr/nodes/ws'
|
32
|
+
require 'rjr/nodes/web'
|
33
|
+
require 'rjr/nodes/local'
|
34
|
+
require 'rjr/nodes/multi'
|
28
35
|
|
29
36
|
server.rb:
|
30
37
|
|
38
|
+
# listen for methods via amqp, websockets, http, and via local calls
|
39
|
+
amqp_node = RJR::Nodes::AMQP.new :node_id => 'server', :broker => 'localhost'
|
40
|
+
ws_node = RJR::Nodes::WS.new :node_id => 'server', :host => 'localhost', :port => 8080
|
41
|
+
www_node = RJR::Nodes::Web.new :node_id => 'server', :host => 'localhost', :port => 8888
|
42
|
+
local_node = RJR::Nodes::Local.new :node_id => 'server'
|
43
|
+
multi_node = RJR::Nodes::Multi.new :nodes => [amqp_node, ws_node, www_node, local_node]
|
44
|
+
|
31
45
|
# define a rpc method called 'hello' which takes
|
32
46
|
# one argument and returns it in upper case
|
33
|
-
|
47
|
+
multi_node.dispatcher.handle("hello") { |arg|
|
34
48
|
arg.upcase
|
35
49
|
}
|
36
50
|
|
37
|
-
# listen for this method via amqp, websockets, http, and via local calls
|
38
|
-
amqp_node = RJR::AMQPNode.new :node_id => 'server', :broker => 'localhost'
|
39
|
-
ws_node = RJR::WSNode.new :node_id => 'server', :host => 'localhost', :port => 8080
|
40
|
-
www_node = RJR::WebNode.new :node_id => 'server', :host => 'localhost', :port => 8888
|
41
|
-
local_node = RJR::LocalNode.new :node_id => 'server'
|
42
|
-
|
43
51
|
# start the server and block
|
44
|
-
multi_node = RJR::MultiNode.new :nodes => [amqp_node, ws_node, www_node, local_node]
|
45
52
|
multi_node.listen
|
46
53
|
multi_node.join
|
47
54
|
|
48
55
|
|
49
56
|
amqp_client.rb:
|
50
57
|
|
51
|
-
# invoke the method over amqp
|
52
|
-
amqp_node = RJR::
|
53
|
-
puts amqp_node.
|
58
|
+
# invoke the method over amqp and return result
|
59
|
+
amqp_node = RJR::Nodes::AMQP.new :node_id => 'client', :broker => 'localhost'
|
60
|
+
puts amqp_node.invoke('server-queue', 'hello', 'world')
|
61
|
+
|
62
|
+
# send a notification via amqp,
|
63
|
+
# notifications immediately return and always return nil
|
64
|
+
amqp_node.notify('server-queue', 'hello', 'world')
|
54
65
|
|
55
66
|
|
56
67
|
ws_client.js:
|
@@ -60,12 +71,15 @@ ws_client.js:
|
|
60
71
|
<script type="text/javascript" src="site/json.js" />
|
61
72
|
<script type="text/javascript" src="site/jrw.js" />
|
62
73
|
<script type="text/javascript">
|
63
|
-
var node = new
|
74
|
+
var node = new Nodes::WS('127.0.0.1', '8080');
|
64
75
|
node.onopen = function(){
|
65
|
-
node.invoke_request('hello', 'rjr'
|
66
|
-
|
67
|
-
|
68
|
-
|
76
|
+
node.invoke_request('hello', 'rjr',
|
77
|
+
function(res){
|
78
|
+
if(res.success)
|
79
|
+
alert(res.result);
|
80
|
+
else
|
81
|
+
alert(res.error);
|
82
|
+
});
|
69
83
|
};
|
70
84
|
node.open();
|
71
85
|
</script>
|
@@ -80,7 +94,7 @@ Generate documentation via
|
|
80
94
|
|
81
95
|
rake yard
|
82
96
|
|
83
|
-
Also see specs for detailed usage.
|
97
|
+
Also see examples and specs for detailed usage.
|
84
98
|
|
85
99
|
### Advanced ###
|
86
100
|
|
@@ -93,28 +107,27 @@ Various metadata fields are made available to json-rpc method handlers through
|
|
93
107
|
instance variables. These include:
|
94
108
|
|
95
109
|
|
96
|
-
|
110
|
+
* @rjr_node
|
97
111
|
* @rjr_node_id
|
98
112
|
* @rjr_node_type
|
99
113
|
* @rjr_callback
|
100
|
-
* @
|
101
|
-
* @
|
102
|
-
* @
|
103
|
-
* @
|
104
|
-
* @
|
105
|
-
* @
|
106
|
-
</pre>
|
114
|
+
* @rjr_headers
|
115
|
+
* @rjr_client_ip
|
116
|
+
* @rjr_client_port
|
117
|
+
* @rjr_method
|
118
|
+
* @rjr_method_args
|
119
|
+
* @rjr_handler
|
107
120
|
|
108
121
|
RJR implements a callback interface through which methods may be invoked on a client
|
109
122
|
after an initial server connection is established. Store and/or invoke @rjr_callback to make
|
110
123
|
use of this.
|
111
124
|
|
112
|
-
|
125
|
+
node.dispatcher.handle("register_callback") do |*args|
|
113
126
|
$my_registry.invoke_me_later {
|
114
127
|
# rjr callback will already be setup to send messages to the correct client
|
115
128
|
@rjr_callback.invoke 'callback_method', 'with', 'custom', 'params'
|
116
129
|
}
|
117
|
-
|
130
|
+
end
|
118
131
|
|
119
132
|
RJR also permits arbitrary headers being set on JSON-RPC requests and responses. These
|
120
133
|
will be stored in the json send to/from nodes, at the same level/scope as the message
|
@@ -122,18 +135,18 @@ will be stored in the json send to/from nodes, at the same level/scope as the me
|
|
122
135
|
in their registered handlers to store additional metadata to extend the JSON-RPC protocol and
|
123
136
|
support any custom subsystems (an auth subsystem for example)
|
124
137
|
|
125
|
-
|
138
|
+
node.dispatcher.handle("login") do |*args|
|
126
139
|
if $my_user_registry.find(:user => args.first, :pass => args.last)
|
127
140
|
@headers['session-id'] = $my_user_registry.create_session.id
|
128
141
|
end
|
129
|
-
|
142
|
+
done
|
130
143
|
|
131
|
-
|
144
|
+
node.dispatcher.add_handler("do_secure_action") do |*args|
|
132
145
|
if $my_user_registry.find(:session_id => @headers['session-id']).nil?
|
133
146
|
raise PermissionError, "invalid session"
|
134
147
|
end
|
135
148
|
# ...
|
136
|
-
|
149
|
+
end
|
137
150
|
|
138
151
|
Of course any custom headers set/used will only be of use to JSON-RPC nodes running
|
139
152
|
RJR as this is not standard JSON-RPC.
|
data/Rakefile
CHANGED
data/bin/rjr-client
CHANGED
@@ -4,9 +4,10 @@
|
|
4
4
|
# Copyright (C) 2013 Mohammed Morsi <mo@morsi.org>
|
5
5
|
# Licensed under the Apache License, Version 2.0
|
6
6
|
|
7
|
-
require 'rubygems'
|
8
7
|
require 'optparse'
|
9
|
-
require 'rjr'
|
8
|
+
require 'rjr/common'
|
9
|
+
require 'rjr/messages'
|
10
|
+
require 'rjr/nodes/easy'
|
10
11
|
|
11
12
|
RJR::Logger.log_level = ::Logger::DEBUG
|
12
13
|
|
@@ -93,13 +94,12 @@ NODES = {config[:transport] => {:node_id => config[:node_id],
|
|
93
94
|
:keep_alive => true} } # conditionally set keep alive?
|
94
95
|
|
95
96
|
cdir = File.dirname(__FILE__)
|
96
|
-
client_path = File.join(ENV['RJR_LOAD_PATH'] || File.join(cdir, '..', '
|
97
|
-
|
98
|
-
require_path client_path
|
97
|
+
client_path = File.join(ENV['RJR_LOAD_PATH'] || File.join(cdir, '..', 'examples', 'client'))
|
99
98
|
|
100
99
|
##########################################################
|
101
100
|
|
102
|
-
node = RJR::
|
101
|
+
node = RJR::Nodes::Easy.new(NODES)
|
102
|
+
node.dispatcher.add_modules(client_path)
|
103
103
|
|
104
104
|
if config[:disconnect]
|
105
105
|
disconnect_thread = Thread.new {
|
@@ -115,8 +115,8 @@ end
|
|
115
115
|
# TODO implement mode == :rand
|
116
116
|
|
117
117
|
# grab message (or rand message)
|
118
|
-
msg = (config[:msg_id] == :rand ? RJR::
|
119
|
-
RJR::
|
118
|
+
msg = (config[:msg_id] == :rand ? RJR::MessageUtil.rand_msg(config[:transport]) :
|
119
|
+
RJR::MessageUtil.message(config[:msg_id]))
|
120
120
|
|
121
121
|
if msg.nil?
|
122
122
|
puts "Invalid message id"
|
@@ -136,9 +136,11 @@ end
|
|
136
136
|
} if msg[:params]
|
137
137
|
|
138
138
|
# invoke request
|
139
|
-
res = node.
|
139
|
+
res = node.invoke(config[:dst], msg[:method], *params)
|
140
140
|
|
141
141
|
# verify and output result
|
142
|
+
puts res
|
143
|
+
puts msg[:result]
|
142
144
|
ress = (msg[:result].nil? ? "" : (msg[:result].call(res) ? "passed" : "failed"))
|
143
145
|
RJR::Logger.info "#{msg[:method]} result #{res} #{ress}"
|
144
146
|
|
data/bin/rjr-server
CHANGED
@@ -4,12 +4,12 @@
|
|
4
4
|
# Copyright (C) 2013 Mohammed Morsi <mo@morsi.org>
|
5
5
|
# Licensed under the Apache License, Version 2.0
|
6
6
|
|
7
|
-
require 'rubygems'
|
8
7
|
require 'optparse'
|
9
|
-
require 'rjr'
|
10
8
|
require 'stringio'
|
11
9
|
|
12
|
-
require 'rjr/
|
10
|
+
#require 'rjr/stats'
|
11
|
+
require 'rjr/common'
|
12
|
+
require 'rjr/nodes/easy'
|
13
13
|
|
14
14
|
##########################################################
|
15
15
|
|
@@ -17,7 +17,7 @@ config = { :node_id => 'rjr_test_server',
|
|
17
17
|
:broker => 'localhost',
|
18
18
|
:host => 'localhost',
|
19
19
|
:tcp_port => 8181,
|
20
|
-
:
|
20
|
+
:web_port => 8888,
|
21
21
|
:ws_port => 8080 }
|
22
22
|
|
23
23
|
optparse = OptionParser.new do |opts|
|
@@ -42,8 +42,8 @@ optparse = OptionParser.new do |opts|
|
|
42
42
|
config[:tcp_port] = p
|
43
43
|
end
|
44
44
|
|
45
|
-
opts.on('--
|
46
|
-
config[:
|
45
|
+
opts.on('--web port', 'Port to listen on for web requests') do |p|
|
46
|
+
config[:web_port] = p
|
47
47
|
end
|
48
48
|
|
49
49
|
opts.on('--ws port', 'Websocket Port to listen on') do |p|
|
@@ -58,12 +58,11 @@ optparse.parse!
|
|
58
58
|
|
59
59
|
NODES = {:amqp => {:node_id => config[:node_id], :broker => config[:broker]},
|
60
60
|
:ws => {:node_id => config[:node_id], :host => config[:host], :port => config[:ws_port]},
|
61
|
-
:
|
61
|
+
:web => {:node_id => config[:node_id], :host => config[:host], :port => config[:web_port]},
|
62
62
|
:tcp => {:node_id => config[:node_id], :host => config[:host], :port => config[:tcp_port]}}
|
63
63
|
|
64
64
|
cdir = File.dirname(__FILE__)
|
65
|
-
server_path = File.join(ENV['RJR_LOAD_PATH'] || File.join(cdir, '..', '
|
66
|
-
require_path server_path
|
65
|
+
server_path = File.join(ENV['RJR_LOAD_PATH'] || File.join(cdir, '..', 'examples', 'server'))
|
67
66
|
|
68
67
|
##########################################################
|
69
68
|
|
@@ -71,4 +70,7 @@ $messages = StringIO.new
|
|
71
70
|
|
72
71
|
RJR::Logger.log_level = ::Logger::DEBUG
|
73
72
|
RJR::Logger.log_to $messages
|
74
|
-
|
73
|
+
|
74
|
+
node = RJR::Nodes::Easy.new(NODES)
|
75
|
+
node.dispatcher.add_modules(server_path)
|
76
|
+
node.stop_on("INT").listen.join
|
data/examples/amqp.rb
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
# A RJR AMQP-node example
|
3
|
+
#
|
4
|
+
# Copyright (C) 2013 Mohammed Morsi <mo@morsi.org>
|
5
|
+
# Licensed under the Apache License, Version 2.0
|
6
|
+
|
7
|
+
require 'rjr/nodes/amqp'
|
8
|
+
|
9
|
+
server = RJR::Nodes::AMQP.new :node_id => 'server', :broker => 'localhost'
|
10
|
+
server.dispatcher.handle('method') { |i|
|
11
|
+
puts "server: #{i}"
|
12
|
+
@rjr_callback.notify "callback", i.downcase
|
13
|
+
"#{i}".upcase
|
14
|
+
}
|
15
|
+
server.listen
|
16
|
+
|
17
|
+
client = RJR::Nodes::AMQP.new :node_id => "client", :broker => 'localhost'
|
18
|
+
client.dispatcher.handle('callback') { |i|
|
19
|
+
puts "callback: #{i}"
|
20
|
+
#client.halt
|
21
|
+
}
|
22
|
+
|
23
|
+
client.notify "server-queue", "method", "Hello World"
|
24
|
+
# => nil
|
25
|
+
|
26
|
+
client.invoke "server-queue", "method", "Hello World"
|
27
|
+
# => HELLO WORLD
|
28
|
+
|
29
|
+
#client.join
|
data/examples/client.rb
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
# default client definitions loaded by bin/rjr-client
|
2
|
+
#
|
3
|
+
# Copyright (C) 2013 Mohammed Morsi <mo@morsi.org>
|
4
|
+
# Licensed under the Apache License, Version 2.0
|
5
|
+
|
6
|
+
include RJR::MessageMixins
|
7
|
+
|
8
|
+
def dispatch_client(dispatcher)
|
9
|
+
dispatcher.handle "client_callback" do |p|
|
10
|
+
RJR::Logger.info "invoked client_callback method #{p}"
|
11
|
+
#amqp_node.invoke_request('stress_test-queue', 'stress', "foozmoney#{client_id}")
|
12
|
+
#amqp_node.stop
|
13
|
+
nil
|
14
|
+
end
|
15
|
+
|
16
|
+
define_message "stress" do
|
17
|
+
{ :method => 'stress',
|
18
|
+
:params => ["<CLIENT_ID>"],
|
19
|
+
:result => lambda { |r| r =~ /foobar.*/ } }
|
20
|
+
end
|
21
|
+
|
22
|
+
define_message "stress_callback" do
|
23
|
+
{ :method => 'stress_callback',
|
24
|
+
:params => ["<CLIENT_ID>"],
|
25
|
+
:transports => [:tcp, :ws, :amqp],
|
26
|
+
:result => lambda { |r| r =~ /barfoo.*/ } }
|
27
|
+
end
|
28
|
+
|
29
|
+
define_message "messages" do
|
30
|
+
{ :method => 'messages'}
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
# A RJR multi-node example
|
3
|
+
#
|
4
|
+
# Copyright (C) 2013 Mohammed Morsi <mo@morsi.org>
|
5
|
+
# Licensed under the Apache License, Version 2.0
|
6
|
+
|
7
|
+
require 'rjr/nodes/amqp'
|
8
|
+
require 'rjr/nodes/tcp'
|
9
|
+
require 'rjr/nodes/ws'
|
10
|
+
require 'rjr/nodes/web'
|
11
|
+
require 'rjr/nodes/local'
|
12
|
+
require 'rjr/nodes/multi'
|
13
|
+
require 'rjr/nodes/easy'
|
14
|
+
|
15
|
+
server1 = RJR::Nodes::AMQP.new :node_id => 'server', :broker => 'localhost'
|
16
|
+
server2 = RJR::Nodes::TCP.new :host => 'localhost', :port => 9789, :node_id => 'server'
|
17
|
+
server3 = RJR::Nodes::WS.new :host => 'localhost', :port => 9788, :node_id => 'server'
|
18
|
+
server4 = RJR::Nodes::Web.new :host => 'localhost', :port => 9787, :node_id => 'server'
|
19
|
+
server5 = RJR::Nodes::Local.new
|
20
|
+
server = RJR::Nodes::Multi.new :nodes => [server1, server2, server3, server4, server5]
|
21
|
+
server.dispatcher.handle('method') { |i|
|
22
|
+
puts "server: #{i}"
|
23
|
+
"#{i}".upcase
|
24
|
+
}
|
25
|
+
server.listen
|
26
|
+
|
27
|
+
client = RJR::Nodes::Easy.new :node_id => 'client',
|
28
|
+
:tcp => { :host => 'localhost', :port => 9666 },
|
29
|
+
:ws => { :host => 'localhost', :port => 9665 },
|
30
|
+
:web => { :host => 'localhost', :port => 9664},
|
31
|
+
:amqp => { :broker => 'localhost' }
|
32
|
+
|
33
|
+
puts client.invoke 'tcp://localhost:9789', 'method', 'Hello World'
|
34
|
+
puts client.invoke 'http://localhost:9787', 'method', 'Hello World'
|
35
|
+
puts client.invoke 'ws://localhost:9788', 'method', 'Hello World'
|
36
|
+
puts client.invoke 'server-queue', 'method', 'Hello World'
|
data/examples/local.rb
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
# A RJR local-node example
|
3
|
+
#
|
4
|
+
# Copyright (C) 2013 Mohammed Morsi <mo@morsi.org>
|
5
|
+
# Licensed under the Apache License, Version 2.0
|
6
|
+
require 'rjr/nodes/local'
|
7
|
+
|
8
|
+
server = RJR::Nodes::Local.new
|
9
|
+
server.dispatcher.handle('method') { |i|
|
10
|
+
puts "server: #{i}"
|
11
|
+
@rjr_callback.notify "callback", i.downcase
|
12
|
+
"#{i}".upcase
|
13
|
+
}
|
14
|
+
server.listen
|
15
|
+
|
16
|
+
# local dispatches to whatever methods are registered at hand
|
17
|
+
client = RJR::Nodes::Local.new :dispatcher => server.dispatcher
|
18
|
+
client.dispatcher.handle('callback') { |i|
|
19
|
+
puts "callback: #{i}"
|
20
|
+
#client.halt
|
21
|
+
}
|
22
|
+
|
23
|
+
client.notify "method", "Hello World"
|
24
|
+
# => nil
|
25
|
+
|
26
|
+
puts client.invoke "method", "Hello World"
|
27
|
+
# => HELLO WORLD
|
28
|
+
|
29
|
+
#client.join
|
data/examples/server.rb
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
# default server definitions loaded by bin/rjr-server
|
2
|
+
#
|
3
|
+
# Copyright (C) 2013 Mohammed Morsi <mo@morsi.org>
|
4
|
+
# Licensed under the Apache License, Version 2.0
|
5
|
+
|
6
|
+
def dispatch_server(dispatcher)
|
7
|
+
dispatcher.handle "messages" do |p|
|
8
|
+
$messages.string.split("\n")
|
9
|
+
end
|
10
|
+
|
11
|
+
dispatcher.handle "failed" do |p|
|
12
|
+
RJR::Logger.info "invoked failed method #{p}"
|
13
|
+
raise ArgumentError, "err #{p}"
|
14
|
+
end
|
15
|
+
|
16
|
+
dispatcher.handle "stress" do |p|
|
17
|
+
RJR::Logger.info "invoked stress method #{p}"
|
18
|
+
"foobar #{p}"
|
19
|
+
end
|
20
|
+
|
21
|
+
dispatcher.handle "stress_callback" do |p|
|
22
|
+
RJR::Logger.info "invoked stress_callback method #{p}"
|
23
|
+
@rjr_callback.notify 'client_callback', p
|
24
|
+
"barfoo #{p}"
|
25
|
+
end
|
26
|
+
end
|
data/examples/tcp.rb
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
# A RJR tcp-node example
|
3
|
+
#
|
4
|
+
# Copyright (C) 2013 Mohammed Morsi <mo@morsi.org>
|
5
|
+
# Licensed under the Apache License, Version 2.0
|
6
|
+
|
7
|
+
require 'rjr/nodes/tcp'
|
8
|
+
|
9
|
+
server = RJR::Nodes::TCP.new :host => 'localhost', :port => 9789, :node_id => "server"
|
10
|
+
server.dispatcher.handle('method') { |i|
|
11
|
+
puts "server: #{i}"
|
12
|
+
@rjr_callback.notify "callback", i.downcase
|
13
|
+
"#{i}".upcase
|
14
|
+
}
|
15
|
+
server.listen
|
16
|
+
|
17
|
+
client = RJR::Nodes::TCP.new :node_id => "client", :host => 'localhost', :port => 9666
|
18
|
+
client.dispatcher.handle('callback') { |i|
|
19
|
+
puts "callback: #{i}"
|
20
|
+
#client.halt
|
21
|
+
}
|
22
|
+
|
23
|
+
client.notify "jsonrpc://localhost:9789", "method", "Hello World"
|
24
|
+
# => nil
|
25
|
+
|
26
|
+
client.invoke "jsonrpc://localhost:9789", "method", "Hello World"
|
27
|
+
# => HELLO WORLD
|
28
|
+
|
29
|
+
#client.join
|
data/examples/web.rb
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
# A RJR web-node example
|
3
|
+
#
|
4
|
+
# Copyright (C) 2013 Mohammed Morsi <mo@morsi.org>
|
5
|
+
# Licensed under the Apache License, Version 2.0
|
6
|
+
|
7
|
+
require 'rjr/nodes/web'
|
8
|
+
|
9
|
+
server = RJR::Nodes::Web.new :host => 'localhost', :port => 9789, :node_id => "server"
|
10
|
+
server.dispatcher.handle('method') { |i|
|
11
|
+
puts "server: #{i}"
|
12
|
+
"#{i}".upcase
|
13
|
+
}
|
14
|
+
server.listen
|
15
|
+
|
16
|
+
client = RJR::Nodes::Web.new :node_id => "client", :host => 'localhost', :port => 9666
|
17
|
+
client.notify "http://localhost:9789", "method", "Hello World"
|
18
|
+
# => nil
|
19
|
+
|
20
|
+
client.invoke "http://localhost:9789", "method", "Hello World"
|
21
|
+
# => HELLO WORLD
|
22
|
+
#client.join
|
data/examples/ws.rb
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
# A RJR ws-node example
|
3
|
+
#
|
4
|
+
# Copyright (C) 2013 Mohammed Morsi <mo@morsi.org>
|
5
|
+
# Licensed under the Apache License, Version 2.0
|
6
|
+
|
7
|
+
require 'rjr/nodes/ws'
|
8
|
+
|
9
|
+
server = RJR::Nodes::WS.new :host => 'localhost', :port => 9789, :node_id => "server"
|
10
|
+
server.dispatcher.handle('method') { |i|
|
11
|
+
puts "server: #{i}"
|
12
|
+
@rjr_callback.notify "callback", i.downcase
|
13
|
+
"#{i}".upcase
|
14
|
+
}
|
15
|
+
server.listen
|
16
|
+
|
17
|
+
client = RJR::Nodes::WS.new :node_id => "client", :host => 'localhost', :port => 9666
|
18
|
+
client.dispatcher.handle('callback') { |i|
|
19
|
+
puts "callback: #{i}"
|
20
|
+
#client.halt
|
21
|
+
}
|
22
|
+
|
23
|
+
client.notify "ws://localhost:9789", "method", "Hello World"
|
24
|
+
# => nil
|
25
|
+
|
26
|
+
client.invoke "ws://localhost:9789", "method", "Hello World"
|
27
|
+
# => HELLO WORLD
|
28
|
+
|
29
|
+
#client.join
|
data/lib/rjr/common.rb
CHANGED
@@ -2,11 +2,17 @@
|
|
2
2
|
#
|
3
3
|
# Assortment of helper methods and methods that don't fit elsewhere
|
4
4
|
#
|
5
|
-
# Copyright (C) 2011-
|
5
|
+
# Copyright (C) 2011-2013 Mohammed Morsi <mo@morsi.org>
|
6
6
|
# Licensed under the Apache License, Version 2.0
|
7
7
|
|
8
8
|
require 'logger'
|
9
9
|
|
10
|
+
# Return a random uuid
|
11
|
+
def gen_uuid
|
12
|
+
["%02x"*4, "%02x"*2, "%02x"*2, "%02x"*2, "%02x"*6].join("-") %
|
13
|
+
Array.new(16) {|x| rand(0xff) }
|
14
|
+
end
|
15
|
+
|
10
16
|
module RJR
|
11
17
|
|
12
18
|
# Logger helper class.
|
@@ -97,17 +103,6 @@ class Object
|
|
97
103
|
end
|
98
104
|
end
|
99
105
|
|
100
|
-
module Kernel
|
101
|
-
def require_path(path)
|
102
|
-
path.split(':').all? { |dir|
|
103
|
-
# TODO also all .so files? allow user to specify suffix or omit?
|
104
|
-
Dir.glob(File.join(dir, '*.rb')).all? { |rb|
|
105
|
-
require rb
|
106
|
-
}
|
107
|
-
}
|
108
|
-
end
|
109
|
-
end
|
110
|
-
|
111
106
|
if RUBY_VERSION < "1.9"
|
112
107
|
# We extend object in ruby 1.9 to define 'instance_exec'
|
113
108
|
#
|