rjr 0.7.0 → 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
data/lib/rjr/ws_node.rb CHANGED
@@ -1,11 +1,10 @@
1
1
  # RJR WebSockets Endpoint
2
2
  #
3
+ # Implements the RJR::Node interface to satisty JSON-RPC requests over the websockets protocol
4
+ #
3
5
  # Copyright (C) 2012 Mohammed Morsi <mo@morsi.org>
4
6
  # Licensed under the Apache License, Version 2.0
5
7
 
6
- # establish client connection w/ specified args and invoke block w/
7
- # newly created client, returning it after block terminates
8
-
9
8
  require 'em-websocket'
10
9
  require 'rjr/web_socket'
11
10
 
@@ -14,14 +13,23 @@ require 'rjr/message'
14
13
 
15
14
  module RJR
16
15
 
17
- # Web Socket client node callback interface,
18
- # send data back to client via established web socket.
16
+ # Web Socket node callback interface, used to invoke json-rpc methods
17
+ # against a remote node via a web socket connection previously established
18
+ #
19
+ # After a node sends a json-rpc request to another, the either node may send
20
+ # additional requests to each other via the socket already established until
21
+ # it is closed on either end
19
22
  class WSNodeCallback
23
+ # WSNodeCallback initializer
24
+ # @param [Hash] args the options to create the websocket node callback with
25
+ # @option args [Socket] :socket socket connection used to send/receive messages
26
+ # @option args [Hash] :headers hash of rjr message headers present in client request when callback is established
20
27
  def initialize(args = {})
21
28
  @socket = args[:socket]
22
29
  @message_headers = args[:headers]
23
30
  end
24
31
 
32
+ # Implementation of {RJR::NodeCallback#invoke}
25
33
  def invoke(callback_method, *data)
26
34
  #msg = CallbackMessage.new(:data => data)
27
35
  msg = RequestMessage.new :method => callback_method, :args => data, :headers => @message_headers
@@ -31,11 +39,37 @@ class WSNodeCallback
31
39
  end
32
40
  end
33
41
 
34
- # Web node definition, listen for and invoke json-rpc requests via web sockets
42
+ # Web socket node definition, listen for and invoke json-rpc requests via web sockets
43
+ #
44
+ # Clients should specify the hostname / port when listening for and invoking requests.
45
+ #
46
+ # *note* the RJR javascript client also supports sending / receiving json-rpc
47
+ # messages over web sockets
48
+ #
49
+ # @example Listening for json-rpc requests over tcp
50
+ # # register rjr dispatchers (see RJR::Dispatcher)
51
+ # RJR::Dispatcher.add_handler('hello') { |name|
52
+ # "Hello #{name}!"
53
+ # }
54
+ #
55
+ # # initialize node, listen, and block
56
+ # server = RJR::WSNode.new :node_id => 'server', :host => 'localhost', :port => '7777'
57
+ # server.listen
58
+ # server.join
59
+ #
60
+ # @example Invoking json-rpc requests over web sockets using rjr
61
+ # client = RJR::WsNode.new :node_id => 'client'
62
+ # puts client.invoke_request('ws://localhost:7777', 'hello', 'mo')
63
+ #
35
64
  class WSNode < RJR::Node
36
65
  RJR_NODE_TYPE = :websockets
37
66
 
38
67
  private
68
+ # Initialize the ws subsystem
69
+ def init_node
70
+ end
71
+
72
+ # Internal helper, handle request message received
39
73
  def handle_request(socket, message)
40
74
  client_port, client_ip = Socket.unpack_sockaddr_in(socket.get_peername)
41
75
  msg = RequestMessage.new(:message => message, :headers => @message_headers)
@@ -56,7 +90,10 @@ class WSNode < RJR::Node
56
90
  end
57
91
 
58
92
  public
59
- # initialize the node w/ the specified params
93
+ # WSNode initializer
94
+ # @param [Hash] args the options to create the web socket node with
95
+ # @option args [String] :host the hostname/ip which to listen on
96
+ # @option args [Integer] :port the port which to listen on
60
97
  def initialize(args = {})
61
98
  super(args)
62
99
  @host = args[:host]
@@ -65,18 +102,19 @@ class WSNode < RJR::Node
65
102
  @connection_event_handlers = {:closed => [], :error => []}
66
103
  end
67
104
 
68
- # register connection event handler
105
+ # Register connection event handler
106
+ # @param [:error, :close] event the event to register the handler for
107
+ # @param [Callable] handler block param to be added to array of handlers that are called when event occurs
108
+ # @yield [WSNode] self is passed to each registered handler when event occurs
69
109
  def on(event, &handler)
70
110
  if @connection_event_handlers.keys.include?(event)
71
111
  @connection_event_handlers[event] << handler
72
112
  end
73
113
  end
74
114
 
75
- # Initialize the ws subsystem
76
- def init_node
77
- end
78
-
79
115
  # Instruct Node to start listening for and dispatching rpc requests
116
+ #
117
+ # Implementation of {RJR::Node#listen}
80
118
  def listen
81
119
  em_run do
82
120
  init_node
@@ -100,6 +138,10 @@ class WSNode < RJR::Node
100
138
  end
101
139
 
102
140
  # Instructs node to send rpc request, and wait for / return response
141
+ # @param [String] uri location of node to send request to, should be
142
+ # in format of ws://hostname:port
143
+ # @param [String] rpc_method json-rpc method to invoke on destination
144
+ # @param [Array] args array of arguments to convert to json and invoke remote method wtih
103
145
  def invoke_request(uri, rpc_method, *args)
104
146
  init_node
105
147
  message = RequestMessage.new :method => rpc_method,
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.7.0
4
+ version: 0.8.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -27,6 +27,38 @@ dependencies:
27
27
  - - ~>
28
28
  - !ruby/object:Gem::Version
29
29
  version: 1.3.0
30
+ - !ruby/object:Gem::Dependency
31
+ name: eventmachine
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ type: :runtime
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ - !ruby/object:Gem::Dependency
47
+ name: json
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ type: :runtime
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
30
62
  description: Ruby Json Rpc library
31
63
  email: mo@morsi.org
32
64
  executables:
@@ -61,7 +93,7 @@ files:
61
93
  - specs/message_spec.rb
62
94
  - LICENSE
63
95
  - Rakefile
64
- - README.rdoc
96
+ - README.md
65
97
  - bin/rjr-server
66
98
  homepage: http://github.com/movitto/rjr
67
99
  licenses: []
@@ -88,3 +120,4 @@ signing_key:
88
120
  specification_version: 3
89
121
  summary: JSON RPC server and client library over amqp, websockets, http, etc
90
122
  test_files: []
123
+ has_rdoc:
data/README.rdoc DELETED
@@ -1,73 +0,0 @@
1
- == RJR - Ruby Json Rpc Library
2
-
3
- Copyright (C) 2012 Mo Morsi <mo@morsi.org>
4
-
5
- RJR is made available under the GNU AFFERO GENERAL PUBLIC LICENSE
6
- as published by the Free Software Foundation, either version 3
7
- of the License, or (at your option) any later version.
8
-
9
- === Intro
10
- To install rjr simply run:
11
- gem install rjr
12
-
13
- Source code is available via:
14
- git clone http://github.com/movitto/rjr
15
-
16
- === Using
17
-
18
- Simply require rubygems and the rjr library
19
-
20
- require 'rubygems'
21
- require 'rjr'
22
-
23
- server.rb:
24
-
25
- # define a rpc method called 'hello' which takes
26
- # one argument and returns it in upper case
27
- RJR::Dispatcher.add_handler("hello") { |arg|
28
- arg.upcase
29
- }
30
-
31
- # listen for this method via amqp, websockets, http, and via local calls
32
- amqp_node = RJR::AMQPNode.new :node_id => 'server', :broker => 'localhost'
33
- ws_node = RJR::WSNode.new :node_id => 'server', :host => 'localhost', :port => 8080
34
- www_node = RJR::WebNode.new :node_id => 'server', :host => 'localhost', :port => 8888
35
- local_node = RJR::LocalNode.new :node_id => 'server'
36
-
37
- # start the server and block
38
- multi_node = RJR::MultiNode.new :nodes => [amqp_node, ws_node, www_node, local_node]
39
- multi_node.listen
40
- multi_node.join
41
-
42
-
43
- amqp_client.rb:
44
-
45
- # invoke the method over amqp
46
- amqp_node = RJR::AMQPNode.new :node_id => 'client', :broker => 'localhost'
47
- puts amqp_node.invoke_request('server-queue', 'hello', 'world')
48
-
49
-
50
- ws_client.js:
51
-
52
- // use the js client to invoke the method via a websocket
53
- <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
54
- <script type="text/javascript" src="site/json.js" />
55
- <script type="text/javascript" src="site/jrw.js" />
56
- <script type="text/javascript">
57
- var node = new WSNode('127.0.0.1', '8080');
58
- node.onopen = function(){
59
- node.invoke_request('hello', 'rjr');
60
- };
61
- node.onsuccess = function(result){
62
- alert(result);
63
- };
64
- node.open();
65
- </script>
66
-
67
- Generate documentation via
68
- rake rdoc
69
-
70
- Also see specs for detailed usage.
71
-
72
- === Authors
73
- Mo Morsi <mo@morsi.org>