Class: Celluloid::IO::TCPSocket
- Inherits:
-
Object
- Object
- Celluloid::IO::TCPSocket
- Extended by:
- Forwardable
- Includes:
- CommonMethods
- Defined in:
- lib/celluloid/io/tcp_socket.rb
Overview
TCPSocket with combined blocking and evented support
Class Method Summary collapse
-
.from_ruby_socket(ruby_socket) ⇒ Object
Convert a Ruby TCPSocket into a Celluloid::IO::TCPSocket.
Instance Method Summary collapse
-
#initialize(remote_host, remote_port, local_host = nil, local_port = nil) ⇒ TCPSocket
constructor
Opens a TCP connection to remote_host on remote_port.
- #to_io ⇒ Object
Methods included from CommonMethods
#acquire_ownership, #evented?, #read, #readpartial, #release_ownership, #wait_readable, #wait_writable, #write
Constructor Details
#initialize(remote_host, remote_port, local_host = nil, local_port = nil) ⇒ TCPSocket
Opens a TCP connection to remote_host on remote_port. If local_host and local_port are specified, then those parameters are used on the local end to establish the connection.
25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 |
# File 'lib/celluloid/io/tcp_socket.rb', line 25 def initialize(remote_host, remote_port, local_host = nil, local_port = nil) # Is it an IPv4 address? begin @addr = Resolv::IPv4.create(remote_host) rescue ArgumentError end # Guess it's not IPv4! Is it IPv6? unless @addr begin @addr = Resolv::IPv6.create(remote_host) rescue ArgumentError end end # Guess it's not an IP address, so let's try DNS unless @addr # TODO: suppport asynchronous DNS # Even EventMachine doesn't do async DNS by default o_O addrs = Array(DNSResolver.new.resolve(remote_host)) raise Resolv::ResolvError, "DNS result has no information for #{remote_host}" if addrs.empty? # Pseudorandom round-robin DNS support :/ @addr = addrs[rand(addrs.size)] end case @addr when Resolv::IPv4 family = Socket::AF_INET when Resolv::IPv6 family = Socket::AF_INET6 else raise ArgumentError, "unsupported address class: #{@addr.class}" end @socket = Socket.new(family, Socket::SOCK_STREAM, 0) @socket.bind Addrinfo.tcp(local_host, local_port) if local_host begin @socket.connect_nonblock Socket.sockaddr_in(remote_port, @addr.to_s) rescue Errno::EINPROGRESS wait_writable retry rescue Errno::EISCONN # We're now connected! Yay exceptions for flow control # NOTE: This is the approach the Ruby stdlib docs suggest ;_; end end |
Class Method Details
.from_ruby_socket(ruby_socket) ⇒ Object
Convert a Ruby TCPSocket into a Celluloid::IO::TCPSocket
15 16 17 18 19 20 |
# File 'lib/celluloid/io/tcp_socket.rb', line 15 def self.from_ruby_socket(ruby_socket) # Some hax here, but whatever ;) socket = allocate socket.instance_variable_set(:@socket, ruby_socket) socket end |
Instance Method Details
#to_io ⇒ Object
73 74 75 |
# File 'lib/celluloid/io/tcp_socket.rb', line 73 def to_io @socket end |