Class: Cosmos::JsonDRbObject
Overview
Used to forward all method calls to the remote server object. Before using this class ensure the remote service has been started in the server class:
json = JsonDrb.new
json.start_service('127.0.0.1', 7777, self)
Now the JsonDRbObject can be used to call server methods directly:
server = JsonDRbObject('127.0.0.1', 7777)
server.cmd(*args)
Instance Method Summary collapse
-
#disconnect ⇒ Object
Disconnects from the JSON server.
-
#initialize(hostname, port, connect_timeout = 1.0) ⇒ JsonDRbObject
constructor
A new instance of JsonDRbObject.
-
#method_missing(method_name, *method_params) ⇒ Object
Forwards all method calls to the remote service.
-
#shutdown ⇒ Object
Permanently disconnects from the JSON server.
Constructor Details
#initialize(hostname, port, connect_timeout = 1.0) ⇒ JsonDRbObject
Returns a new instance of JsonDRbObject.
36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
# File 'lib/cosmos/io/json_drb_object.rb', line 36 def initialize(hostname, port, connect_timeout = 1.0) hostname = '127.0.0.1' if (hostname.to_s.upcase == 'LOCALHOST') begin @addr = Socket.pack_sockaddr_in(port, hostname) rescue => error if error. =~ /getaddrinfo/ raise "Invalid hostname: #{hostname}" else raise error end end @hostname = hostname @port = port @mutex = Mutex.new @socket = nil @id = 0 @request_in_progress = false @connect_timeout = connect_timeout @connect_timeout = @connect_timeout.to_f if @connect_timeout @shutdown = false end |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(method_name, *method_params) ⇒ Object
Forwards all method calls to the remote service.
76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 |
# File 'lib/cosmos/io/json_drb_object.rb', line 76 def method_missing(method_name, *method_params) @mutex.synchronize do raise DRb::DRbConnError, "Shutdown" if @shutdown if !@socket or @socket.closed? or @request_in_progress if @request_in_progress disconnect() @socket = nil @request_in_progress = false end begin addr = Socket.pack_sockaddr_in(@port, @hostname) @socket = Socket.new(Socket::AF_INET, Socket::SOCK_STREAM, 0) @socket.setsockopt(Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1) begin @socket.connect_nonblock(addr) rescue IO::WaitWritable begin _, sockets, _ = IO.select(nil, [@socket], nil, @connect_timeout) # wait 3-way handshake completion rescue IOError, Errno::ENOTSOCK disconnect() @socket = nil raise "Connect canceled" end if sockets and !sockets.empty? begin @socket.connect_nonblock(addr) # check connection failure rescue IOError, Errno::ENOTSOCK disconnect() @socket = nil raise "Connect canceled" rescue Errno::EINPROGRESS retry rescue Errno::EISCONN, Errno::EALREADY end else disconnect() @socket = nil raise "Connect timeout" end rescue IOError, Errno::ENOTSOCK disconnect() @socket = nil raise "Connect canceled" end rescue => e raise DRb::DRbConnError, e. end end request = JsonRpcRequest.new(method_name, method_params, @id) @id += 1 request_data = request.to_json(:allow_nan => true) begin @request_in_progress = true STDOUT.puts "Request:\n" if JsonDRb.debug? STDOUT.puts request_data if JsonDRb.debug? JsonDRb.send_data(@socket, request_data) response_data = JsonDRb.(@socket, '') STDOUT.puts "\nResponse:\n" if JsonDRb.debug? STDOUT.puts response_data if JsonDRb.debug? @request_in_progress = false rescue => e disconnect() @socket = nil raise DRb::DRbConnError, e., e.backtrace end if response_data response = JsonRpcResponse.from_json(response_data) if JsonRpcErrorResponse === response if response.error.data raise Exception.from_hash(response.error.data) else raise "JsonDRb Error (#{response.error.code}): #{response.error.}" end else return response.result end else # Socket was closed by server disconnect() @socket = nil raise DRb::DRbConnError, "Socket closed by server" end end end |
Instance Method Details
#disconnect ⇒ Object
Disconnects from the JSON server
59 60 61 |
# File 'lib/cosmos/io/json_drb_object.rb', line 59 def disconnect Cosmos.close_socket(@socket) end |
#shutdown ⇒ Object
Permanently disconnects from the JSON server
64 65 66 67 |
# File 'lib/cosmos/io/json_drb_object.rb', line 64 def shutdown @shutdown = true disconnect() end |