rjr 0.12.2 → 0.15.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
#
|