Class: DRb::DRbTCPSocket

Inherits:
Object
  • Object
show all
Defined in:
lib/drb/drb.rb

Overview

The default drb protocol which communicates over a TCP socket.

The DRb TCP protocol URI looks like: druby://<host>:<port>?<option>. The option is optional.

Direct Known Subclasses

DRbSSLSocket, DRbUNIXSocket

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(uri, soc, config = {}) ⇒ DRbTCPSocket

Create a new DRbTCPSocket instance.

uri is the URI we are connected to. soc is the tcp socket we are bound to. config is our configuration.



898
899
900
901
902
903
904
905
# File 'lib/drb/drb.rb', line 898

def initialize(uri, soc, config={})
  @uri = uri
  @socket = soc
  @config = config
  @acl = config[:tcp_acl]
  @msg = DRbMessage.new(config)
  set_sockopt(@socket)
end

Instance Attribute Details

#uriObject (readonly)

Get the URI that we are connected to.



908
909
910
# File 'lib/drb/drb.rb', line 908

def uri
  @uri
end

Class Method Details

.getservernameObject

Returns the hostname of this server



844
845
846
847
848
849
850
851
# File 'lib/drb/drb.rb', line 844

def self.getservername
  host = Socket::gethostname
  begin
    Socket::gethostbyname(host)[0]
  rescue
    'localhost'
  end
end

.open(uri, config) ⇒ Object

Open a client connection to uri (DRb URI string) using configuration config.

This can raise DRb::DRbBadScheme or DRb::DRbBadURI if uri is not for a recognized protocol. See DRb::DRbServer.new for information on built-in URI protocols.



835
836
837
838
839
840
841
# File 'lib/drb/drb.rb', line 835

def self.open(uri, config)
  host, port, = parse_uri(uri)
  host.untaint
  port.untaint
  soc = TCPSocket.open(host, port)
  self.new(uri, soc, config)
end

.open_server(uri, config) ⇒ Object

Open a server listening for connections at uri using configuration config.



871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
# File 'lib/drb/drb.rb', line 871

def self.open_server(uri, config)
  uri = 'druby://:0' unless uri
  host, port, _ = parse_uri(uri)
  config = {:tcp_original_host => host}.update(config)
  if host.size == 0
    host = getservername
    soc = open_server_inaddr_any(host, port)
  else
    soc = TCPServer.open(host, port)
  end
  port = soc.addr[1] if port == 0
  config[:tcp_port] = port
  uri = "druby://#{host}:#{port}"
  self.new(uri, soc, config)
end

.open_server_inaddr_any(host, port) ⇒ Object

For the families available for host, returns a TCPServer on port. If port is 0 the first available port is used. IPv4 servers are preferred over IPv6 servers.



856
857
858
859
860
861
862
863
864
865
866
867
# File 'lib/drb/drb.rb', line 856

def self.open_server_inaddr_any(host, port)
  infos = Socket::getaddrinfo(host, nil,
                              Socket::AF_UNSPEC,
                              Socket::SOCK_STREAM,
                              0,
                              Socket::AI_PASSIVE)
  families = Hash[*infos.collect { |af, *_| af }.uniq.zip([]).flatten]
  return TCPServer.open('0.0.0.0', port) if families.has_key?('AF_INET')
  return TCPServer.open('::', port) if families.has_key?('AF_INET6')
  return TCPServer.open(port)
  # :stopdoc:
end

.uri_option(uri, config) ⇒ Object

Parse uri into a [uri, option] pair.



888
889
890
891
# File 'lib/drb/drb.rb', line 888

def self.uri_option(uri, config)
  host, port, option = parse_uri(uri)
  return "druby://#{host}:#{port}", option
end

Instance Method Details

#acceptObject

On the server side, for an instance returned by #open_server, accept a client connection and return a new instance to handle the server’s side of this client-server session.



957
958
959
960
961
962
963
964
965
966
967
968
969
# File 'lib/drb/drb.rb', line 957

def accept
  while true
    s = @socket.accept
    break if (@acl ? @acl.allow_socket?(s) : true)
    s.close
  end
  if @config[:tcp_original_host].to_s.size == 0
    uri = "druby://#{s.addr[3]}:#{@config[:tcp_port]}"
  else
    uri = @uri
  end
  self.class.new(uri, s, @config)
end

#alive?Boolean

Check to see if this connection is alive.

Returns:

  • (Boolean)


972
973
974
975
976
977
978
979
# File 'lib/drb/drb.rb', line 972

def alive?
  return false unless @socket
  if IO.select([@socket], nil, nil, 0)
    close
    return false
  end
  true
end

#closeObject

Close the connection.

If this is an instance returned by #open_server, then this stops listening for new connections altogether. If this is an instance returned by #open or by #accept, then it closes this particular client-server session.



947
948
949
950
951
952
# File 'lib/drb/drb.rb', line 947

def close
  if @socket
    @socket.close
    @socket = nil
  end
end

#peeraddrObject

Get the address of our TCP peer (the other end of the socket we are bound to.



912
913
914
# File 'lib/drb/drb.rb', line 912

def peeraddr
  @socket.peeraddr
end

#recv_replyObject

On the client side, receive a reply from the server.



935
936
937
# File 'lib/drb/drb.rb', line 935

def recv_reply
  @msg.recv_reply(stream)
end

#recv_requestObject

On the server side, receive a request from the client.



925
926
927
# File 'lib/drb/drb.rb', line 925

def recv_request
  @msg.recv_request(stream)
end

#send_reply(succ, result) ⇒ Object

On the server side, send a reply to the client.



930
931
932
# File 'lib/drb/drb.rb', line 930

def send_reply(succ, result)
  @msg.send_reply(stream, succ, result)
end

#send_request(ref, msg_id, arg, b) ⇒ Object

On the client side, send a request to the server.



920
921
922
# File 'lib/drb/drb.rb', line 920

def send_request(ref, msg_id, arg, b)
  @msg.send_request(stream, ref, msg_id, arg, b)
end

#set_sockopt(soc) ⇒ Object

:nodoc:



981
982
983
984
# File 'lib/drb/drb.rb', line 981

def set_sockopt(soc) # :nodoc:
  soc.setsockopt(Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1)
  soc.fcntl(Fcntl::F_SETFD, Fcntl::FD_CLOEXEC) if defined? Fcntl::FD_CLOEXEC
end

#streamObject

Get the socket.



917
# File 'lib/drb/drb.rb', line 917

def stream; @socket; end