simplerpc 0.2.4 → 0.3.0c
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.
- checksums.yaml +4 -4
- data/lib/simplerpc.rb +4 -6
- data/lib/simplerpc/client.rb +55 -37
- data/lib/simplerpc/exceptions.rb +36 -0
- data/lib/simplerpc/server.rb +55 -18
- data/lib/simplerpc/socket_protocol.rb +8 -12
- data/lib/simplerpc/version.rb +5 -0
- metadata +13 -11
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 727d91ba2fea5bec49b44ad808dd37eef9d6f800
|
4
|
+
data.tar.gz: 70950f3bf04baa1f281926e748554dee0623edb7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e3894eeff293db5d898c4ae87d7d83f840ee9e18e0356cb77af5ce9d6e17bcf70aa5b2d672d80d05e30e071d97b32fe66f7bb7c8ed40db3584de247e9e4fe29a
|
7
|
+
data.tar.gz: 3ba4862e358f939cd462506492dfeaf27a5589a49bba8c0af3f7ecaccc494015d2f72a474dcf8dbb8e620c9847526ee4344fe152d95357ce0c56a72f49527839
|
data/lib/simplerpc.rb
CHANGED
@@ -1,7 +1,4 @@
|
|
1
1
|
|
2
|
-
require 'simplerpc/server'
|
3
|
-
require 'simplerpc/client'
|
4
|
-
|
5
2
|
# SimpleRPC is a very simple RPC library for ruby, designed to be as fast as possible whilst still
|
6
3
|
# retaining a simple API.
|
7
4
|
#
|
@@ -14,7 +11,8 @@ require 'simplerpc/client'
|
|
14
11
|
# This module simply contains version information,
|
15
12
|
# and including it includes all other project files
|
16
13
|
module SimpleRPC
|
17
|
-
|
18
|
-
|
19
|
-
|
14
|
+
require_relative 'simplerpc/exceptions'
|
15
|
+
require_relative 'simplerpc/server'
|
16
|
+
require_relative 'simplerpc/client'
|
17
|
+
require_relative 'simplerpc/version'
|
20
18
|
end
|
data/lib/simplerpc/client.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
require 'socket'
|
2
2
|
require 'simplerpc/socket_protocol'
|
3
|
+
require 'simplerpc/exceptions'
|
3
4
|
|
4
5
|
# rubocop:disable LineLength
|
5
6
|
|
@@ -11,30 +12,6 @@ module SimpleRPC
|
|
11
12
|
class AuthenticationError < StandardError
|
12
13
|
end
|
13
14
|
|
14
|
-
# Thrown when the server raises an exception.
|
15
|
-
#
|
16
|
-
# The message is set to the server's exception class.
|
17
|
-
class RemoteException < Exception
|
18
|
-
|
19
|
-
attr_reader :remote_exception
|
20
|
-
|
21
|
-
def initialize(exception)
|
22
|
-
super(exception)
|
23
|
-
@remote_exception = exception
|
24
|
-
end
|
25
|
-
|
26
|
-
# Return the backtrace from the original (remote)
|
27
|
-
# exception
|
28
|
-
def backtrace
|
29
|
-
@remote_exception.backtrace
|
30
|
-
end
|
31
|
-
|
32
|
-
# Return a string representing the remote exception
|
33
|
-
def to_s
|
34
|
-
@remote_exception.to_s
|
35
|
-
end
|
36
|
-
end
|
37
|
-
|
38
15
|
# The superclass of a proxy object
|
39
16
|
class RemoteObject < BasicObject
|
40
17
|
end
|
@@ -97,7 +74,8 @@ module SimpleRPC
|
|
97
74
|
#
|
98
75
|
# == Exceptions
|
99
76
|
#
|
100
|
-
# Remote exceptions fired by the server during a call are
|
77
|
+
# Remote exceptions fired by the server during a call are returned as RemoteExceptions,
|
78
|
+
# and have the message and backtrace set as if you are on the remote server.
|
101
79
|
#
|
102
80
|
# Network errors are exposed directly. The server will not close a pipe during
|
103
81
|
# an operation, so if using connect-on-demand you should only observe
|
@@ -160,8 +138,8 @@ module SimpleRPC
|
|
160
138
|
#
|
161
139
|
class Client
|
162
140
|
|
163
|
-
attr_reader :hostname, :port, :threaded
|
164
|
-
attr_accessor :serialiser, :
|
141
|
+
attr_reader :hostname, :port, :threaded, :timeout
|
142
|
+
attr_accessor :serialiser, :fast_auth
|
165
143
|
attr_writer :password, :secret
|
166
144
|
|
167
145
|
# Create a new client for the network.
|
@@ -187,7 +165,8 @@ module SimpleRPC
|
|
187
165
|
@hostname = opts[:hostname] || '127.0.0.1'
|
188
166
|
@port = opts[:port]
|
189
167
|
raise 'Port required' unless @port
|
190
|
-
|
168
|
+
timeout = opts[:timeout]
|
169
|
+
|
191
170
|
|
192
171
|
# Support multiple connections at once?
|
193
172
|
@threaded = !(opts[:threaded] == false)
|
@@ -216,6 +195,20 @@ module SimpleRPC
|
|
216
195
|
end
|
217
196
|
end
|
218
197
|
|
198
|
+
|
199
|
+
# Set the timeout on all socket operations,
|
200
|
+
# including connection
|
201
|
+
def timeout=(timeout)
|
202
|
+
@timeout = timeout
|
203
|
+
@socket_timeout = nil
|
204
|
+
|
205
|
+
if @timeout.to_f > 0
|
206
|
+
secs = @timeout.floor
|
207
|
+
usecs = (@timeout - secs).floor * 1_000_000
|
208
|
+
@socket_timeout = [secs, usecs].pack("l_2")
|
209
|
+
end
|
210
|
+
end
|
211
|
+
|
219
212
|
# Connect to the remote server and return two things:
|
220
213
|
#
|
221
214
|
# * A proxy object for communicating with the server
|
@@ -296,6 +289,9 @@ module SimpleRPC
|
|
296
289
|
end
|
297
290
|
end
|
298
291
|
end
|
292
|
+
rescue EOFError, Errno::ECONNRESET, Errno::ETIMEDOUT,
|
293
|
+
Errno::ECONNREFUSED, Errno::ECONNABORTED, Errno::EPIPE => e
|
294
|
+
raise ConnectionError.new(e)
|
299
295
|
end
|
300
296
|
|
301
297
|
# Close all persistent connections to the server.
|
@@ -344,23 +340,28 @@ module SimpleRPC
|
|
344
340
|
_get_socket() do |s, persist|
|
345
341
|
|
346
342
|
# send method name and arity
|
347
|
-
SocketProtocol::Stream.send(s, [m, args, block_given?, persist], @serialiser
|
343
|
+
SocketProtocol::Stream.send(s, [m, args, block_given?, persist], @serialiser)
|
348
344
|
|
349
345
|
# Call with args
|
350
|
-
success, result = SocketProtocol::Stream.recv(s, @serialiser
|
346
|
+
success, result = SocketProtocol::Stream.recv(s, @serialiser)
|
351
347
|
|
352
348
|
# Check if we should yield
|
353
349
|
while success == SocketProtocol::REQUEST_YIELD do
|
354
350
|
block_result = yield(*result)
|
355
|
-
SocketProtocol::Stream.send(s, block_result, @serialiser
|
356
|
-
success, result = SocketProtocol::Stream.recv(s, @serialiser
|
351
|
+
SocketProtocol::Stream.send(s, block_result, @serialiser)
|
352
|
+
success, result = SocketProtocol::Stream.recv(s, @serialiser)
|
357
353
|
end
|
358
354
|
|
359
355
|
end
|
360
356
|
|
361
357
|
# If it didn't succeed, treat the payload as an exception
|
362
|
-
raise
|
358
|
+
raise result unless success == SocketProtocol::REQUEST_SUCCESS
|
363
359
|
return result
|
360
|
+
rescue EOFError, Errno::ECONNRESET, Errno::ETIMEDOUT,
|
361
|
+
Errno::ECONNREFUSED, Errno::ECONNABORTED, Errno::EPIPE => e
|
362
|
+
raise ConnectionError.new(e)
|
363
|
+
rescue StandardError => e
|
364
|
+
raise FormatError.new(e)
|
364
365
|
end
|
365
366
|
|
366
367
|
# Returns a proxy object that is all but indistinguishable
|
@@ -403,21 +404,32 @@ module SimpleRPC
|
|
403
404
|
# Connect to the server and return a socket
|
404
405
|
def _connect
|
405
406
|
# Connect to the host
|
406
|
-
s = Socket.tcp(@hostname, @port, nil, nil, connect_timeout: @timeout)
|
407
|
+
# s = Socket.tcp(@hostname, @port, nil, nil, connect_timeout: @timeout)
|
408
|
+
s = Socket.new( Socket::AF_INET, Socket::SOCK_STREAM, 0 )
|
407
409
|
|
408
410
|
# Disable Nagle's algorithm
|
409
411
|
s.setsockopt(Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1)
|
410
412
|
|
413
|
+
# Set timeout directly on socket
|
414
|
+
if @socket_timeout
|
415
|
+
s.setsockopt(Socket::SOL_SOCKET, Socket::SO_RCVTIMEO, @socket_timeout)
|
416
|
+
s.setsockopt(Socket::SOL_SOCKET, Socket::SO_SNDTIMEO, @socket_timeout)
|
417
|
+
end
|
418
|
+
|
419
|
+
|
420
|
+
s.connect( Socket.pack_sockaddr_in( @port, @hostname.to_s ) )
|
421
|
+
|
422
|
+
|
411
423
|
# if auth is required
|
412
424
|
if @password && @secret
|
413
|
-
salt = SocketProtocol::Simple.recv(s
|
425
|
+
salt = SocketProtocol::Simple.recv(s)
|
414
426
|
challenge = Encryption.encrypt(@password, @secret, salt)
|
415
427
|
|
416
|
-
SocketProtocol::Simple.send(s, challenge
|
428
|
+
SocketProtocol::Simple.send(s, challenge)
|
417
429
|
|
418
430
|
# Check return if not @fast_auth
|
419
431
|
unless @fast_auth
|
420
|
-
unless SocketProtocol::Simple.recv(s
|
432
|
+
unless SocketProtocol::Simple.recv(s) == SocketProtocol::AUTH_SUCCESS
|
421
433
|
s.close
|
422
434
|
raise AuthenticationError, 'Authentication failed'
|
423
435
|
end
|
@@ -501,4 +513,10 @@ module SimpleRPC
|
|
501
513
|
|
502
514
|
end
|
503
515
|
|
516
|
+
|
517
|
+
class FastClient
|
518
|
+
|
519
|
+
end
|
520
|
+
|
521
|
+
|
504
522
|
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
|
2
|
+
|
3
|
+
|
4
|
+
|
5
|
+
module SimpleRPC
|
6
|
+
|
7
|
+
# Superclass of all RPC-related exceptions
|
8
|
+
class RPCError < Exception
|
9
|
+
|
10
|
+
attr_reader :cause
|
11
|
+
|
12
|
+
def initialize(exception)
|
13
|
+
super("#{exception.class}: #{exception}")
|
14
|
+
set_backtrace(exception.backtrace)
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
18
|
+
|
19
|
+
|
20
|
+
# Called when the serialiser fails to deserialise something
|
21
|
+
class FormatError < RPCError
|
22
|
+
end
|
23
|
+
|
24
|
+
# Called when the connection fails
|
25
|
+
class ConnectionError < RPCError
|
26
|
+
end
|
27
|
+
|
28
|
+
# Thrown when the server raises an exception.
|
29
|
+
#
|
30
|
+
# The message is set to the server's exception class.
|
31
|
+
class RemoteException < RPCError
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
|
36
|
+
|
data/lib/simplerpc/server.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
|
2
2
|
require 'socket' # Get sockets from stdlib
|
3
3
|
require 'simplerpc/socket_protocol'
|
4
|
+
require 'simplerpc/exceptions'
|
4
5
|
|
5
6
|
# rubocop:disable LineLength
|
6
7
|
|
@@ -76,8 +77,8 @@ module SimpleRPC
|
|
76
77
|
#
|
77
78
|
class Server
|
78
79
|
|
79
|
-
attr_reader :hostname, :port, :obj, :threaded
|
80
|
-
attr_accessor :verbose_errors, :serialiser, :
|
80
|
+
attr_reader :hostname, :port, :obj, :threaded, :timeout
|
81
|
+
attr_accessor :verbose_errors, :serialiser, :fast_auth
|
81
82
|
attr_writer :password, :secret
|
82
83
|
|
83
84
|
# Create a new server for a given proxy object.
|
@@ -121,7 +122,7 @@ module SimpleRPC
|
|
121
122
|
@close_in, @close_out = UNIXSocket.pair
|
122
123
|
|
123
124
|
# Connect/receive timeouts
|
124
|
-
|
125
|
+
timeout = opts[:timeout]
|
125
126
|
|
126
127
|
# Auth
|
127
128
|
if opts[:password] && opts[:secret]
|
@@ -143,6 +144,21 @@ module SimpleRPC
|
|
143
144
|
@ml = Mutex.new
|
144
145
|
end
|
145
146
|
|
147
|
+
|
148
|
+
# Set the timeout on all socket operations,
|
149
|
+
# including connection
|
150
|
+
def timeout=(timeout)
|
151
|
+
@timeout = timeout
|
152
|
+
@socket_timeout = nil
|
153
|
+
|
154
|
+
if @timeout.to_f > 0
|
155
|
+
secs = @timeout.floor
|
156
|
+
usecs = (@timeout - secs).floor * 1_000_000
|
157
|
+
@socket_timeout = [secs, usecs].pack("l_2")
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
|
146
162
|
# Start listening forever.
|
147
163
|
#
|
148
164
|
# Use threads and .close to stop the server.
|
@@ -160,6 +176,13 @@ module SimpleRPC
|
|
160
176
|
|
161
177
|
# Accept in an interruptable manner
|
162
178
|
if (c = interruptable_accept(s))
|
179
|
+
|
180
|
+
# Set timeout directly on socket
|
181
|
+
if @socket_timeout
|
182
|
+
c.setsockopt(Socket::SOL_SOCKET, Socket::SO_RCVTIMEO, @socket_timeout)
|
183
|
+
c.setsockopt(Socket::SOL_SOCKET, Socket::SO_SNDTIMEO, @socket_timeout)
|
184
|
+
end
|
185
|
+
|
163
186
|
# Threaded
|
164
187
|
if @threaded
|
165
188
|
|
@@ -196,6 +219,7 @@ module SimpleRPC
|
|
196
219
|
|
197
220
|
# Close socket
|
198
221
|
@close = false if @close # say we've closed
|
222
|
+
ensure
|
199
223
|
@ml.unlock
|
200
224
|
end
|
201
225
|
|
@@ -204,7 +228,7 @@ module SimpleRPC
|
|
204
228
|
# Returns 0 if :threaded is set to false.
|
205
229
|
def active_client_threads
|
206
230
|
# If threaded return a count from the clients list
|
207
|
-
return @
|
231
|
+
return @clients.length if @threaded
|
208
232
|
|
209
233
|
# Else return 0 if not threaded
|
210
234
|
return 0
|
@@ -212,13 +236,25 @@ module SimpleRPC
|
|
212
236
|
|
213
237
|
# Close the server object nicely,
|
214
238
|
# waiting on threads if necessary
|
215
|
-
def close
|
239
|
+
def close(timeout = false)
|
240
|
+
# Return immediately if the server isn't listening
|
241
|
+
return unless @ml.locked?
|
242
|
+
|
216
243
|
# Ask the loop to close
|
217
244
|
@close_in.putc 'x' # Tell select to close
|
218
245
|
|
246
|
+
|
219
247
|
# Wait for loop to end
|
220
|
-
|
221
|
-
@ml.
|
248
|
+
elapsed_time = 0
|
249
|
+
while @ml.locked? do
|
250
|
+
sleep(0.05)
|
251
|
+
elapsed_time += 0.05
|
252
|
+
|
253
|
+
# If a timeout is given, try killing threads at this point
|
254
|
+
if timeout && elapsed_time > timeout
|
255
|
+
@clients.each {|id, thread| thread.kill() }
|
256
|
+
end
|
257
|
+
end
|
222
258
|
end
|
223
259
|
|
224
260
|
private
|
@@ -232,8 +268,6 @@ module SimpleRPC
|
|
232
268
|
def interruptable_accept(s)
|
233
269
|
c = IO.select([s, @close_out], nil, nil)
|
234
270
|
|
235
|
-
# puts "--> #{c}"
|
236
|
-
|
237
271
|
return nil unless c
|
238
272
|
if c[0][0] == @close_out
|
239
273
|
# @close is set, so consume from socket
|
@@ -244,6 +278,7 @@ module SimpleRPC
|
|
244
278
|
return nil
|
245
279
|
end
|
246
280
|
return s.accept if !@close && c
|
281
|
+
return nil
|
247
282
|
rescue IOError
|
248
283
|
# cover 'closed stream' errors
|
249
284
|
return nil
|
@@ -266,17 +301,17 @@ module SimpleRPC
|
|
266
301
|
rescue NotImplementedError
|
267
302
|
salt = Random.new.bytes(@salt_size)
|
268
303
|
end
|
269
|
-
SocketProtocol::Simple.send(c, salt
|
304
|
+
SocketProtocol::Simple.send(c, salt)
|
270
305
|
|
271
306
|
# Receive encrypted challenge
|
272
|
-
raw = SocketProtocol::Simple.recv(c
|
307
|
+
raw = SocketProtocol::Simple.recv(c)
|
273
308
|
|
274
309
|
# D/c if failed
|
275
310
|
unless Encryption.decrypt(raw, @secret, salt) == @password
|
276
|
-
SocketProtocol::Simple.send(c, SocketProtocol::AUTH_FAIL
|
311
|
+
SocketProtocol::Simple.send(c, SocketProtocol::AUTH_FAIL) unless @fast_auth
|
277
312
|
return
|
278
313
|
end
|
279
|
-
SocketProtocol::Simple.send(c, SocketProtocol::AUTH_SUCCESS
|
314
|
+
SocketProtocol::Simple.send(c, SocketProtocol::AUTH_SUCCESS) unless @fast_auth
|
280
315
|
rescue
|
281
316
|
# Auth failure is silent for the server
|
282
317
|
return
|
@@ -288,7 +323,7 @@ module SimpleRPC
|
|
288
323
|
while !@close && persist do
|
289
324
|
|
290
325
|
# Note, when clients d/c this throws EOFError
|
291
|
-
m, args, remote_block_given, persist = SocketProtocol::Stream.recv(c, @serialiser
|
326
|
+
m, args, remote_block_given, persist = SocketProtocol::Stream.recv(c, @serialiser)
|
292
327
|
# puts "Method: #{m}, args: #{args}, block?: #{remote_block_given}, persist: #{persist}"
|
293
328
|
|
294
329
|
if m && args
|
@@ -303,8 +338,8 @@ module SimpleRPC
|
|
303
338
|
if remote_block_given
|
304
339
|
# Proxy with a block that sends back to the client
|
305
340
|
result = @obj.send(m, *args) do |*yield_args|
|
306
|
-
SocketProtocol::Stream.send(c, [SocketProtocol::REQUEST_YIELD, yield_args], @serialiser
|
307
|
-
SocketProtocol::Stream.recv(c, @serialiser
|
341
|
+
SocketProtocol::Stream.send(c, [SocketProtocol::REQUEST_YIELD, yield_args], @serialiser)
|
342
|
+
SocketProtocol::Stream.recv(c, @serialiser)
|
308
343
|
end
|
309
344
|
|
310
345
|
else
|
@@ -313,13 +348,15 @@ module SimpleRPC
|
|
313
348
|
end
|
314
349
|
|
315
350
|
rescue StandardError => se
|
316
|
-
|
351
|
+
# Ensure the passed exception has no class hierarchy from
|
352
|
+
# this object space (which would not work on the client)
|
353
|
+
result = RemoteException.new(se)
|
317
354
|
success = SocketProtocol::REQUEST_FAIL
|
318
355
|
end
|
319
356
|
|
320
357
|
# Send over the result
|
321
358
|
# puts "[s] sending result..."
|
322
|
-
SocketProtocol::Stream.send(c, [success, result], @serialiser
|
359
|
+
SocketProtocol::Stream.send(c, [success, result], @serialiser)
|
323
360
|
else
|
324
361
|
persist = false
|
325
362
|
end
|
@@ -38,14 +38,12 @@ module SimpleRPC
|
|
38
38
|
module Stream
|
39
39
|
|
40
40
|
# Send using a serialiser writing through the socket
|
41
|
-
def self.send(s, obj, serialiser
|
42
|
-
raise Errno::ETIMEDOUT unless IO.select([], [s], [], timeout)
|
41
|
+
def self.send(s, obj, serialiser)
|
43
42
|
return serialiser.dump(obj, s)
|
44
43
|
end
|
45
44
|
|
46
45
|
# Recieve using a serialiser reading from the socket
|
47
|
-
def self.recv(s, serialiser
|
48
|
-
raise Errno::ETIMEDOUT unless IO.select([s], [], [], timeout)
|
46
|
+
def self.recv(s, serialiser)
|
49
47
|
return serialiser.load(s)
|
50
48
|
end
|
51
49
|
|
@@ -59,40 +57,38 @@ module SimpleRPC
|
|
59
57
|
module Simple
|
60
58
|
|
61
59
|
# Send a buffer
|
62
|
-
def self.send(s, buf
|
60
|
+
def self.send(s, buf)
|
63
61
|
# Dump into buffer
|
64
62
|
buflen = buf.length
|
65
63
|
|
66
64
|
# Send buffer length
|
67
|
-
raise Errno::ETIMEDOUT unless IO.select([], [s], [], timeout)
|
68
65
|
s.puts(buflen)
|
69
66
|
|
70
67
|
# Send buffer
|
71
68
|
sent = 0
|
72
|
-
while sent < buflen
|
69
|
+
while sent < buflen do
|
73
70
|
sent += s.write(buf[sent..-1])
|
74
71
|
end
|
75
|
-
raise Errno::ETIMEDOUT unless x
|
72
|
+
# raise Errno::ETIMEDOUT unless x
|
76
73
|
|
77
74
|
end
|
78
75
|
|
79
76
|
# Receive a buffer
|
80
|
-
def self.recv(s
|
81
|
-
raise Errno::ETIMEDOUT unless IO.select([s], [], [], timeout)
|
77
|
+
def self.recv(s)
|
82
78
|
buflen = s.gets.to_s.chomp.to_i
|
83
79
|
|
84
80
|
return nil if buflen <= 0
|
85
81
|
|
86
82
|
buf = ''
|
87
83
|
recieved = 0
|
88
|
-
while recieved < buflen
|
84
|
+
while recieved < buflen do
|
89
85
|
str = s.read(buflen - recieved)
|
90
86
|
buf += str
|
91
87
|
recieved += str.length
|
92
88
|
end
|
93
|
-
raise Errno::ETIMEDOUT unless x
|
94
89
|
|
95
90
|
return buf
|
91
|
+
|
96
92
|
end
|
97
93
|
|
98
94
|
end
|
metadata
CHANGED
@@ -1,48 +1,50 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: simplerpc
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0c
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Stephen Wattam
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2016-04-25 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: A very simple and fast RPC library
|
14
|
-
email: stephenwattam
|
14
|
+
email: steve@stephenwattam.com
|
15
15
|
executables: []
|
16
16
|
extensions: []
|
17
17
|
extra_rdoc_files: []
|
18
18
|
files:
|
19
|
+
- "./lib/simplerpc.rb"
|
20
|
+
- LICENSE
|
21
|
+
- lib/simplerpc/client.rb
|
19
22
|
- lib/simplerpc/encryption.rb
|
23
|
+
- lib/simplerpc/exceptions.rb
|
20
24
|
- lib/simplerpc/server.rb
|
21
25
|
- lib/simplerpc/socket_protocol.rb
|
22
|
-
- lib/simplerpc/
|
23
|
-
- ./lib/simplerpc.rb
|
24
|
-
- LICENSE
|
26
|
+
- lib/simplerpc/version.rb
|
25
27
|
homepage: http://stephenwattam.com/projects/simplerpc
|
26
28
|
licenses:
|
27
29
|
- Beerware
|
28
30
|
metadata: {}
|
29
|
-
post_install_message:
|
31
|
+
post_install_message:
|
30
32
|
rdoc_options: []
|
31
33
|
require_paths:
|
32
34
|
- lib
|
33
35
|
required_ruby_version: !ruby/object:Gem::Requirement
|
34
36
|
requirements:
|
35
|
-
- -
|
37
|
+
- - ">="
|
36
38
|
- !ruby/object:Gem::Version
|
37
39
|
version: '2.0'
|
38
40
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
39
41
|
requirements:
|
40
|
-
- -
|
42
|
+
- - ">"
|
41
43
|
- !ruby/object:Gem::Version
|
42
|
-
version:
|
44
|
+
version: 1.3.1
|
43
45
|
requirements: []
|
44
46
|
rubyforge_project:
|
45
|
-
rubygems_version: 2.
|
47
|
+
rubygems_version: 2.5.1
|
46
48
|
signing_key:
|
47
49
|
specification_version: 4
|
48
50
|
summary: Simple RPC library
|