em-jsonrpc 0.0.2

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.
@@ -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
+