em-jsonrpc 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,207 @@
1
+ require "eventmachine"
2
+ require "yajl"
3
+ require "securerandom"
4
+
5
+ require "em-jsonrpc/version"
6
+ require "em-jsonrpc/constants"
7
+
8
+
9
+ module EventMachine::JsonRPC
10
+
11
+ class Client < EM::Connection
12
+ DEFAULT_REQUEST_TIMEOUT = 2
13
+
14
+ attr_reader :pending_requests
15
+
16
+ def initialize(host, port, request_timeout = nil, parser_options = {})
17
+ @host = host
18
+ @port = port
19
+ @request_timeout = request_timeout || DEFAULT_REQUEST_TIMEOUT
20
+ @parser_options = parser_options
21
+
22
+ if parser_options and parser_options[:symbolize_keys]
23
+ @key_jsonrpc = :jsonrpc
24
+ @key_id = :id
25
+ @key_result = :result
26
+ @key_error = :error
27
+ @key_code = :code
28
+ @key_message = :message
29
+ else
30
+ @key_jsonrpc = KEY_JSONRPC
31
+ @key_id = KEY_ID
32
+ @key_result = KEY_RESULT
33
+ @key_error = KEY_ERROR
34
+ @key_code = KEY_CODE
35
+ @key_message = KEY_MESSAGE
36
+ end
37
+
38
+ @pending_requests = {}
39
+ @connected = false
40
+ end
41
+
42
+ def post_init
43
+ @encoder = Yajl::Encoder.new
44
+ end
45
+
46
+ def connection_completed
47
+ @connected = true
48
+ @parser = Yajl::Parser.new @parser_options
49
+ @parser.on_parse_complete = method(:obj_parsed)
50
+ @state = :data
51
+ ready
52
+ end
53
+
54
+ def unbind
55
+ @pending_requests.clear
56
+
57
+ if @connected
58
+ connection_terminated
59
+ else
60
+ connection_failed
61
+ end
62
+ @connected = false
63
+ end
64
+
65
+ def connected?
66
+ @connected
67
+ end
68
+
69
+ def ready
70
+ end
71
+
72
+ def connection_failed
73
+ end
74
+
75
+ def connection_terminated
76
+ end
77
+
78
+ def connect_again
79
+ reconnect @host, @port
80
+ end
81
+
82
+ def send_request(method, params=nil)
83
+ id = SecureRandom.hex 4
84
+ request = Request.new self, id
85
+ request.timeout @request_timeout
86
+ @pending_requests[id] = request
87
+
88
+ jsonrpc_request = {
89
+ KEY_JSONRPC => VALUE_VERSION,
90
+ KEY_ID => id,
91
+ KEY_METHOD => method
92
+ }
93
+ jsonrpc_request[KEY_PARAMS] = params if params
94
+ send_data @encoder.encode jsonrpc_request
95
+
96
+ return request
97
+ end
98
+
99
+ def receive_data(data)
100
+ case @state
101
+ when :data
102
+ parse_data(data)
103
+ when :ignore
104
+ nil
105
+ end
106
+ end
107
+
108
+ def parse_data(data)
109
+ begin
110
+ @parser << data
111
+ rescue Yajl::ParseError => e
112
+ close_connection
113
+ @connected = false
114
+ @state = :ignore
115
+ parsing_error
116
+ cancel_pending_requests "response parsing error"
117
+ end
118
+ end
119
+
120
+ def obj_parsed(obj)
121
+ case obj
122
+ when Hash
123
+ process(obj)
124
+ when Array
125
+ # Do nothing, just ignore.
126
+ end
127
+ end
128
+
129
+ def process(obj)
130
+ return unless (id = obj[@key_id]) and id.is_a? String
131
+ return unless request = @pending_requests[id]
132
+
133
+ request.delete
134
+
135
+ unless obj[@key_jsonrpc] == "2.0"
136
+ request.fail :invalid_response, "invalid response: doesn't include \"jsonrpc\": \"2.0\""
137
+ return
138
+ end
139
+
140
+ if obj.has_key? @key_result
141
+ request.succeed obj[@key_result]
142
+ return
143
+ elsif error = obj[@key_error]
144
+ if error.is_a? Hash and (code = error[@key_code]) and (message = error[@key_message])
145
+ request.fail :error, error
146
+ return
147
+ else
148
+ request.fail :invalid_response, "invalid response: \"error\" is not a valid object"
149
+ return
150
+ end
151
+ else
152
+ request.fail :invalid_response, "invalid response: not valid \"result\" or \"error\""
153
+ return
154
+ end
155
+ end
156
+
157
+ def parsing_error
158
+ end
159
+
160
+ def cancel_pending_requests description
161
+ @pending_requests.each_value do |request|
162
+ request.fail :canceled, "request canceled: #{description}"
163
+ end
164
+ @pending_requests.clear
165
+ end
166
+
167
+
168
+ class Request
169
+ include EM::Deferrable
170
+
171
+ def initialize(client, id)
172
+ @client = client
173
+ @id = id
174
+ end
175
+
176
+ def delete
177
+ @client.pending_requests.delete @id
178
+ end
179
+
180
+ # Override EM::Deferrable#timeout method so the errback is executed passing
181
+ # a :request_timeout single argument.
182
+ # Also, the request is removed from the list of pending requests.
183
+ def timeout seconds
184
+ cancel_timeout
185
+ me = self
186
+ @deferred_timeout = EM::Timer.new(seconds) do
187
+ me.delete
188
+ me.fail :request_timeout
189
+ end
190
+ end
191
+ end # class Request
192
+
193
+ end # class Client
194
+
195
+
196
+ class ConnectionError < StandardError ; end
197
+
198
+
199
+ def self.connect_tcp(host, port, handler, request_timeout=nil, parser_options={}, &block)
200
+ raise Error, "EventMachine is not running" unless EM.reactor_running?
201
+
202
+ EM.connect(host, port, handler, host, port, request_timeout, parser_options, &block)
203
+ end
204
+
205
+ end
206
+
207
+
@@ -0,0 +1,39 @@
1
+ module EventMachine::JsonRPC
2
+
3
+ CODE_INVALID_JSON = -32700
4
+ MSG_INVALID_JSON = "invalid JSON"
5
+
6
+ CODE_INVALID_REQUEST = -32600
7
+ MSG_INVALID_REQ_JSONRPC = "invalid request: doesn't include \"jsonrpc\": \"2.0\""
8
+ MSG_INVALID_REQ_ID = "invalid request: wrong id"
9
+ MSG_INVALID_REQ_METHOD = "invalid request: wrong method"
10
+ MSG_INVALID_REQ_PARAMS = "invalid request: wrong params"
11
+
12
+ CODE_METHOD_NOT_FOUND = -32601
13
+ MSG_METHOD_NOT_FOUND = "method not found"
14
+
15
+ CODE_INVALID_PARAMS = -32602
16
+ MSG_INVALID_PARAMS = "invalid parameter(s)"
17
+
18
+ CODE_INTERNAL_ERROR = -32603
19
+ MSG_INTERNAL_ERROR = "internal error"
20
+
21
+ PARSING_ERROR_RESPONSE = "{\"jsonrpc\":\"2.0\",\"id\":null,\"error\":{" \
22
+ "\"code\":#{CODE_INVALID_JSON}," \
23
+ "\"message\":\"#{MSG_INVALID_JSON}\"}}"
24
+
25
+ BATCH_NOT_SUPPORTED_RESPONSE = "{\"jsonrpc\":\"2.0\",\"id\":null,\"error\":{" \
26
+ "\"code\":-32099," \
27
+ "\"message\":\"batch mode not implemented\"}}"
28
+
29
+ KEY_JSONRPC = "jsonrpc"
30
+ VALUE_VERSION = "2.0"
31
+ KEY_ID = "id"
32
+ KEY_METHOD = "method"
33
+ KEY_PARAMS = "params"
34
+ KEY_RESULT = "result"
35
+ KEY_ERROR = "error"
36
+ KEY_CODE = "code"
37
+ KEY_MESSAGE = "message"
38
+
39
+ end
@@ -0,0 +1,215 @@
1
+ require "eventmachine"
2
+ require "yajl"
3
+
4
+ require "em-jsonrpc/version"
5
+ require "em-jsonrpc/constants"
6
+
7
+
8
+ module EventMachine::JsonRPC
9
+
10
+ class Server < EM::Connection
11
+ attr_reader :encoder
12
+
13
+ def initialize(*options)
14
+ parser_options = options.first || {}
15
+
16
+ if parser_options[:symbolize_keys]
17
+ @key_jsonrpc = :jsonrpc
18
+ @key_id = :id
19
+ @key_method = :method
20
+ @key_params = :params
21
+ else
22
+ @key_jsonrpc = KEY_JSONRPC
23
+ @key_id = KEY_ID
24
+ @key_method = KEY_METHOD
25
+ @key_params = KEY_PARAMS
26
+ end
27
+
28
+ @parser = Yajl::Parser.new parser_options
29
+ @parser.on_parse_complete = method(:obj_parsed)
30
+
31
+ @state = :data
32
+ end
33
+
34
+ def receive_data(data)
35
+ case @state
36
+ when :data
37
+ parse_data(data)
38
+ when :ignore
39
+ nil
40
+ end
41
+ end
42
+
43
+ def parse_data(data)
44
+ begin
45
+ @parser << data
46
+ rescue Yajl::ParseError => e
47
+ send_data PARSING_ERROR_RESPONSE
48
+ close_connection_after_writing
49
+ @state = :ignore
50
+ parsing_error data, e
51
+ end
52
+ end
53
+
54
+ def obj_parsed(obj)
55
+ @encoder ||= Yajl::Encoder.new
56
+
57
+ case obj
58
+ # Individual request/notification.
59
+ when Hash
60
+ process(obj)
61
+ # Batch: multiple requests/notifications in an array.
62
+ # NOTE: Not implemented as it doesn't make sense using JSON RPC over pure TCP / UnixSocket.
63
+ when Array
64
+ send_data BATCH_NOT_SUPPORTED_RESPONSE
65
+ close_connection_after_writing
66
+ @state = :ignore
67
+ batch_not_supported_error obj
68
+ end
69
+ end
70
+
71
+ def process(obj)
72
+ is_request = obj.has_key?(@key_id)
73
+ id = obj[@key_id]
74
+
75
+ if is_request
76
+ unless id.is_a? String or id.is_a? Fixnum or id.is_a? NilClass
77
+ invalid_request obj, CODE_INVALID_REQUEST, MSG_INVALID_REQ_ID
78
+ reply_error nil, CODE_INVALID_REQUEST, MSG_INVALID_REQ_ID
79
+ return false
80
+ end
81
+ end
82
+
83
+ unless obj[@key_jsonrpc] == "2.0"
84
+ invalid_request obj, CODE_INVALID_REQUEST, MSG_INVALID_REQ_JSONRPC
85
+ reply_error id, CODE_INVALID_REQUEST, MSG_INVALID_REQ_JSONRPC
86
+ return false
87
+ end
88
+
89
+ unless (method = obj[@key_method]).is_a? String
90
+ invalid_request obj, CODE_INVALID_REQUEST, MSG_INVALID_REQ_METHOD
91
+ reply_error id, CODE_INVALID_REQUEST, MSG_INVALID_REQ_METHOD
92
+ return false
93
+ end
94
+
95
+ if (params = obj[@key_params])
96
+ unless params.is_a? Array or params.is_a? Hash
97
+ invalid_request obj, CODE_INVALID_REQUEST, MSG_INVALID_REQ_PARAMS
98
+ reply_error id, CODE_INVALID_REQUEST, MSG_INVALID_REQ_PARAMS
99
+ return false
100
+ end
101
+ end
102
+
103
+ if is_request
104
+ receive_request Request.new(self, id, method, params)
105
+ else
106
+ receive_notification method, params
107
+ end
108
+ end
109
+
110
+ # This method must be overriden in the user's inherited class.
111
+ def receive_request(request)
112
+ puts "request received:\n#{request.inspect}"
113
+ end
114
+
115
+ # This method must be overriden in the user's inherited class.
116
+ def receive_notification(method, params)
117
+ puts "notification received (method: #{method.inspect}, params: #{params.inspect})"
118
+ end
119
+
120
+ def reply_error(id, code, message)
121
+ send_data @encoder.encode({
122
+ KEY_JSONRPC => VALUE_VERSION,
123
+ KEY_ID => id,
124
+ KEY_ERROR => {
125
+ KEY_CODE => code,
126
+ KEY_MESSAGE => message
127
+ }
128
+ })
129
+ end
130
+
131
+ # This method could be overriden in the user's inherited class.
132
+ def parsing_error(data, exception)
133
+ $stderr.puts "parsing error:\n#{exception.message}"
134
+ end
135
+
136
+ # This method could be overriden in the user's inherited class.
137
+ def batch_not_supported_error(obj)
138
+ $stderr.puts "batch request received but not implemented"
139
+ end
140
+
141
+ # This method could be overriden in the user's inherited class.
142
+ def invalid_request(obj, code, message=nil)
143
+ $stderr.puts "error #{code}: #{message}"
144
+ end
145
+
146
+
147
+ class Request
148
+ attr_reader :rpc_method, :params, :id
149
+
150
+ def initialize(conn, id, rpc_method, params)
151
+ @conn = conn
152
+ @id = id
153
+ @rpc_method = rpc_method
154
+ @params = params
155
+ end
156
+
157
+ def reply_result(result)
158
+ return nil if @conn.error?
159
+
160
+ response = {
161
+ KEY_JSONRPC => VALUE_VERSION,
162
+ KEY_ID => @id,
163
+ KEY_RESULT => result
164
+ }
165
+
166
+ # Send the response in chunks (good in case of a big response).
167
+ begin
168
+ @conn.encoder.encode(response) do |chunk|
169
+ @conn.send_data(chunk)
170
+ end
171
+ return true
172
+ rescue Yajl::EncodeError => e
173
+ reply_internal_error "response encode error: #{e.message}"
174
+ return false
175
+ end
176
+ end
177
+
178
+ def reply_internal_error(message=nil)
179
+ return nil if @conn.error?
180
+ @conn.reply_error(@id, CODE_INTERNAL_ERROR, message || MSG_INTERNAL_ERROR)
181
+ end
182
+
183
+ def reply_method_not_found(message=nil)
184
+ return nil if @conn.error?
185
+ @conn.reply_error(@id, CODE_METHOD_NOT_FOUND, message || MSG_METHOD_NOT_FOUND)
186
+ end
187
+
188
+ def reply_invalid_params(message=nil)
189
+ return nil if @conn.error?
190
+ @conn.reply_error(@id, CODE_INVALID_PARAMS, message || MSG_INVALID_PARAMS)
191
+ end
192
+
193
+ def reply_custom_error(code, message)
194
+ return nil if @conn.error?
195
+ unless code.is_a? Integer and (-32099..-32000).include? code
196
+ raise ArgumentError, "code must be an integer between -32099 and -32000"
197
+ end
198
+ @conn.reply_error(@id, code, message)
199
+ end
200
+ end # class Request
201
+
202
+ end # class Server
203
+
204
+
205
+ def self.start_tcp_server(addr, port, handler, options=nil, &block)
206
+ raise Error, "EventMachine is not running" unless EM.reactor_running?
207
+ EM.start_server addr, port, handler, options, &block
208
+ end
209
+
210
+ def self.start_unix_domain_server(filename, handler, options=nil, &block)
211
+ raise Error, "EventMachine is not running" unless EM.reactor_running?
212
+ EM.start_unix_domain_server filename, handler, options, &block
213
+ end
214
+
215
+ end
@@ -0,0 +1,5 @@
1
+ module EventMachine
2
+ module JsonRPC
3
+ VERSION = "0.0.2"
4
+ end
5
+ end
@@ -0,0 +1,139 @@
1
+ #!/usr/bin/ruby
2
+ # coding: utf-8
3
+
4
+ require "test/unit"
5
+ require "rubygems"
6
+ require "yajl"
7
+ require "socket"
8
+ require "timeout"
9
+
10
+
11
+ class TestJsonRPC < Test::Unit::TestCase
12
+
13
+ def initialize(*args)
14
+ super
15
+ @socket = TCPSocket.new "127.0.0.1", 8888
16
+ @parser = Yajl::Parser.new
17
+ @parser.on_parse_complete = method(:response_parsed)
18
+ @encoder = Yajl::Encoder.new
19
+ end
20
+
21
+ def send_request(request)
22
+ @response = nil
23
+ @socket.send request, 0
24
+
25
+ begin
26
+ Timeout.timeout(0.2) do
27
+ while true do
28
+ begin
29
+ data = @socket.recv_nonblock 1024
30
+ @parser << data
31
+ return @response if @response
32
+ rescue IO::WaitReadable #Errno::EAGAIN
33
+ IO.select([@socket])
34
+ retry
35
+ end
36
+ end
37
+ end
38
+ rescue Timeout::Error
39
+ return nil
40
+ end
41
+ end
42
+
43
+ def response_parsed(response)
44
+ @response = response
45
+ end
46
+
47
+ def test_01_rpc_call_with_positional_parameters
48
+ reply = send_request '{"jsonrpc": "2.0", "method": "subtract", "params": [42, 23], "id": 1}'
49
+ assert_equal( {"jsonrpc"=>"2.0", "result"=>19, "id"=>1}, reply )
50
+ end
51
+
52
+ def test_02_rpc_call_with_positional_parameters
53
+ reply = send_request '{"jsonrpc": "2.0", "method": "subtract", "params": [23, 42], "id": 2}'
54
+ assert_equal( {"jsonrpc"=>"2.0", "result"=>-19, "id"=>2}, reply )
55
+ end
56
+
57
+ def test_03_rpc_call_with_named_parameters
58
+ reply = send_request '{"jsonrpc": "2.0", "method": "subtract", "params": {"subtrahend": 23, "minuend": 42}, "id": 3}'
59
+ assert_equal( {"jsonrpc"=>"2.0", "result"=>19, "id"=>3}, reply )
60
+ end
61
+
62
+ def test_04_rpc_call_with_named_parameters
63
+ reply = send_request '{"jsonrpc": "2.0", "method": "subtract", "params": {"minuend": 42, "subtrahend": 23}, "id": 4}'
64
+ assert_equal( {"jsonrpc"=>"2.0", "result"=>19, "id"=>4}, reply )
65
+ end
66
+
67
+ def test_05_a_notification
68
+ reply = send_request '{"jsonrpc": "2.0", "method": "update", "params": [1,2,3,4,5]}'
69
+ assert_equal( nil, reply )
70
+ end
71
+
72
+ def test_06_rpc_call_of_non_existent_method
73
+ reply = send_request '{"jsonrpc": "2.0", "method": "foobar", "id": "1"}'
74
+ assert_equal( {"jsonrpc"=>"2.0", "error"=>{"code"=>-32601, "message"=>"method not found"}, "id"=>"1"}, reply )
75
+ end
76
+
77
+ def test_07_rpc_call_with_invalid_JSON
78
+ reply = send_request '{"jsonrpc": "2.0", "method": "foobar, "params": "bar", "baz]'
79
+ assert_equal( {"jsonrpc"=>"2.0", "error"=>{"code"=>-32700, "message"=>"invalid JSON"}, "id"=>nil}, reply )
80
+ end
81
+
82
+ def test_08_rpc_call_with_invalid_Request_object
83
+ reply = send_request '{"jsonrpc": "2.0", "method": 1, "params": "bar"}'
84
+ assert_equal( {"jsonrpc"=>"2.0", "error" =>{"code"=>-32600, "message"=>"invalid request: wrong method"}, "id"=>nil}, reply )
85
+ end
86
+
87
+ def test_09_rpc_call_Batch_invalid_JSON
88
+ reply = send_request '[ {"jsonrpc": "2.0", "method": "sum", "params": [1,2,4], "id": "1"},{"jsonrpc": "2.0", "method" ]'
89
+ assert_equal( {"jsonrpc"=>"2.0", "error"=>{"code"=>-32700, "message"=>"invalid JSON"}, "id"=>nil}, reply )
90
+ end
91
+
92
+ # NOTE: Batch mode is not implemented so following tests don't make sense.
93
+ #
94
+ # def test_10_rpc_call_with_an_empty_Array
95
+ # reply = send_request '[]'
96
+ # assert_equal( {"jsonrpc"=>"2.0", "error"=>{"code"=>-32600, "message"=>"invalid JSON"}, "id"=>nil}, reply )
97
+ # end
98
+ #
99
+ # def test_11_rpc_call_with_an_invalid_Batch_but_not_empty
100
+ # reply = send_request '[1]'
101
+ # assert_equal( [{"jsonrpc"=>"2.0", "error"=>{"code"=>-32600, "message"=>"Invalid Request."}, "id"=>nil}], reply )
102
+ # end
103
+ #
104
+ # def test_12_rpc_call_with_invalid_Batch
105
+ # reply = send_request '[1,2,3]'
106
+ # assert_equal( [
107
+ # {"jsonrpc"=>"2.0", "error"=>{"code"=>-32600, "message"=>"invalid JSON"}, "id"=>nil},
108
+ # {"jsonrpc"=>"2.0", "error"=>{"code"=>-32600, "message"=>"invalid JSON"}, "id"=>nil},
109
+ # {"jsonrpc"=>"2.0", "error"=>{"code"=>-32600, "message"=>"invalid JSON"}, "id"=>nil}
110
+ # ], reply )
111
+ # end
112
+ #
113
+ # def test_13_rpc_call_Batch
114
+ # reply = send_request '[
115
+ # {"jsonrpc": "2.0", "method": "sum", "params": [1,2,4], "id": "1"},
116
+ # {"jsonrpc": "2.0", "method": "notify_hello", "params": [7]},
117
+ # {"jsonrpc": "2.0", "method": "subtract", "params": [42,23], "id": "2"},
118
+ # {"foo": "boo"},
119
+ # {"jsonrpc": "2.0", "method": "foo.get", "params": {"name": "myself"}, "id": "5"},
120
+ # {"jsonrpc": "2.0", "method": "get_data", "id": "9"}
121
+ # ]'
122
+ # assert_equal( [
123
+ # {"jsonrpc"=>"2.0", "result"=>7, "id"=>"1"},
124
+ # {"jsonrpc"=>"2.0", "result"=>19, "id"=>"2"},
125
+ # {"jsonrpc"=>"2.0", "error"=>{"code"=>-32600, "message"=>"invalid JSON"}, "id"=>nil},
126
+ # {"jsonrpc"=>"2.0", "error"=>{"code"=>-32601, "message"=>"method not found."}, "id"=>"5"},
127
+ # {"jsonrpc"=>"2.0", "result"=>["hello", 5], "id"=>"9"}
128
+ # ], reply )
129
+ # end
130
+ #
131
+ # def test_14_rpc_call_Batch_all_notifications
132
+ # reply = send_request '[
133
+ # {"jsonrpc": "2.0", "method": "notify_sum", "params": [1,2,4]},
134
+ # {"jsonrpc": "2.0", "method": "notify_hello", "params": [7]}
135
+ # ]'
136
+ # assert_equal( nil, reply )
137
+ # end
138
+
139
+ end
@@ -0,0 +1,61 @@
1
+ #!/usr/bin/ruby
2
+ # coding: utf-8
3
+
4
+ ### TMP
5
+ $LOAD_PATH.insert 0, File.expand_path(File.join(File.dirname(__FILE__), "../", "lib"))
6
+ require "em-jsonrpc/server"
7
+
8
+
9
+ class MyJsonRpcServer < EM::JsonRPC::Server
10
+
11
+ def receive_request(request)
12
+ puts "request received:"
13
+ puts "- id : #{request.id.inspect}"
14
+ puts "- method : #{request.rpc_method.inspect}"
15
+ puts "- params : #{request.params.inspect}"
16
+
17
+ case request.rpc_method
18
+
19
+ when /^(subtract|\-)$/
20
+ if request.params.is_a? Array
21
+ minued = request.params[0].to_i
22
+ subtrahend = request.params[1].to_i
23
+ elsif request.params.is_a? Hash
24
+ minued = request.params[:minuend].to_i
25
+ subtrahend = request.params[:subtrahend].to_i
26
+ end
27
+ result = minued - subtrahend
28
+ request.reply_result(result)
29
+
30
+ when /^(sum|\+)$/
31
+ if request.params.is_a? Array
32
+ sum1 = request.params[0].to_i
33
+ sum2 = request.params[1].to_i
34
+ elsif request.params.is_a? Hash
35
+ sum1 = request.params[:minuend].to_i
36
+ sum2 = request.params[:subtrahend].to_i
37
+ end
38
+ result = sum1 + sum2
39
+ request.reply_result(result)
40
+
41
+ else
42
+ request.reply_method_not_found
43
+ end
44
+ end
45
+
46
+ end
47
+
48
+
49
+ EM.run do
50
+ yajl_options = { :symbolize_keys => true }
51
+
52
+ EM::JsonRPC.start_tcp_server("0.0.0.0", 8888, MyJsonRpcServer, yajl_options) do |conn|
53
+ puts "\nnew TCP connection"
54
+ conn.set_comm_inactivity_timeout 120
55
+ end
56
+
57
+ EM::JsonRPC.start_unix_domain_server("/tmp/borrame", MyJsonRpcServer, yajl_options) do |conn|
58
+ puts "\nnew UnixSocket connection"
59
+ conn.set_comm_inactivity_timeout 120
60
+ end
61
+ end
metadata ADDED
@@ -0,0 +1,98 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: em-jsonrpc
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 0
8
+ - 2
9
+ version: 0.0.2
10
+ platform: ruby
11
+ authors:
12
+ - "I\xC3\xB1aki Baz Castillo"
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2012-01-02 00:00:00 +01:00
18
+ default_executable:
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: eventmachine
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ none: false
25
+ requirements:
26
+ - - ">="
27
+ - !ruby/object:Gem::Version
28
+ segments:
29
+ - 0
30
+ version: "0"
31
+ type: :runtime
32
+ version_requirements: *id001
33
+ - !ruby/object:Gem::Dependency
34
+ name: yajl-ruby
35
+ prerelease: false
36
+ requirement: &id002 !ruby/object:Gem::Requirement
37
+ none: false
38
+ requirements:
39
+ - - ">="
40
+ - !ruby/object:Gem::Version
41
+ segments:
42
+ - 0
43
+ - 8
44
+ - 0
45
+ version: 0.8.0
46
+ type: :runtime
47
+ version_requirements: *id002
48
+ description: em-jsonrpc provides a JSON RPC 2.0 TCP/UnixSocket client and server to be integrated within EventMachine reactor
49
+ email: ibc@aliax.net
50
+ executables: []
51
+
52
+ extensions: []
53
+
54
+ extra_rdoc_files: []
55
+
56
+ files:
57
+ - lib/em-jsonrpc/version.rb
58
+ - lib/em-jsonrpc/constants.rb
59
+ - lib/em-jsonrpc/server.rb
60
+ - lib/em-jsonrpc/client.rb
61
+ - test/test-em-jsonrpc-client.rb
62
+ - test/test-em-jsonrpc-server.rb
63
+ has_rdoc: true
64
+ homepage: https://github.com/ibc/em-jsonrpc
65
+ licenses: []
66
+
67
+ post_install_message:
68
+ rdoc_options: []
69
+
70
+ require_paths:
71
+ - lib
72
+ required_ruby_version: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ">="
76
+ - !ruby/object:Gem::Version
77
+ segments:
78
+ - 1
79
+ - 8
80
+ - 7
81
+ version: 1.8.7
82
+ required_rubygems_version: !ruby/object:Gem::Requirement
83
+ none: false
84
+ requirements:
85
+ - - ">="
86
+ - !ruby/object:Gem::Version
87
+ segments:
88
+ - 0
89
+ version: "0"
90
+ requirements: []
91
+
92
+ rubyforge_project:
93
+ rubygems_version: 1.3.7
94
+ signing_key:
95
+ specification_version: 3
96
+ summary: JSON RCP 2.0 client and server for EventMachine over TCP or UnixSocket
97
+ test_files: []
98
+