Class: Celluloid::IO::TCPSocket
- Extended by:
- Forwardable
- Defined in:
- lib/celluloid/io/tcp_socket.rb
Overview
TCPSocket with combined blocking and evented support
Constant Summary
Constants inherited from Stream
Instance Attribute Summary
Attributes inherited from Stream
Class Method Summary collapse
-
.from_ruby_socket(ruby_socket) ⇒ Object
Convert a Ruby TCPSocket into a Celluloid::IO::TCPSocket DEPRECATED: to be removed in a future release.
-
.open(*args, &block) ⇒ Object
Open a TCP socket, yielding it to the given block and closing it automatically when done (if a block is given).
Instance Method Summary collapse
-
#initialize(remote_host, remote_port = nil, local_host = nil, local_port = nil) ⇒ TCPSocket
constructor
Opens a TCP connection to remote_host on remote_port.
-
#recv(maxlen, flags = nil) ⇒ Object
Receives a message.
-
#send(msg, flags, dest_sockaddr = nil) ⇒ Object
Send a message.
- #to_io ⇒ Object
Methods inherited from Stream
#<<, #close, #each, #each_byte, #eof?, #flush, #getc, #gets, #print, #printf, #puts, #read, #readchar, #readline, #readlines, #readpartial, #sysread, #syswrite, #ungetc, #wait_readable, #wait_writable, #write
Constructor Details
#initialize(remote_host, remote_port = nil, 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.
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 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 |
# File 'lib/celluloid/io/tcp_socket.rb', line 38 def initialize(remote_host, remote_port = nil, local_host = nil, local_port = nil) super() # Allow users to pass in a Ruby TCPSocket directly if remote_host.is_a? ::TCPSocket @addr = nil @socket = remote_host return elsif remote_port.nil? raise ArgumentError, "wrong number of arguments (1 for 2)" end # 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 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 # HAX: for some reason we need to finish_connect ourselves on JRuby # This logic is unnecessary but JRuby still throws Errno::EINPROGRESS # if we retry the non-blocking connect instead of just finishing it retry unless defined?(JRUBY_VERSION) && @socket.to_channel.finish_connect 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 DEPRECATED: to be removed in a future release
31 32 33 |
# File 'lib/celluloid/io/tcp_socket.rb', line 31 def self.from_ruby_socket(ruby_socket) new(ruby_socket) end |
.open(*args, &block) ⇒ Object
Open a TCP socket, yielding it to the given block and closing it automatically when done (if a block is given)
15 16 17 18 19 20 21 22 23 24 25 26 27 |
# File 'lib/celluloid/io/tcp_socket.rb', line 15 def self.open(*args, &block) sock = new(*args) if block_given? begin yield sock ensure sock.close end end sock end |
Instance Method Details
#recv(maxlen, flags = nil) ⇒ Object
Receives a message
104 105 106 107 |
# File 'lib/celluloid/io/tcp_socket.rb', line 104 def recv(maxlen, flags = nil) raise NotImplementedError, "flags not supported" if flags && !flags.zero? readpartial(maxlen) end |
#send(msg, flags, dest_sockaddr = nil) ⇒ Object
Send a message
110 111 112 113 114 |
# File 'lib/celluloid/io/tcp_socket.rb', line 110 def send(msg, flags, dest_sockaddr = nil) raise NotImplementedError, "dest_sockaddr not supported" if dest_sockaddr raise NotImplementedError, "flags not supported" unless flags.zero? write(msg) end |
#to_io ⇒ Object
99 100 101 |
# File 'lib/celluloid/io/tcp_socket.rb', line 99 def to_io @socket end |