Class: Celluloid::IO::TCPSocket
- Extended by:
- Forwardable
- Defined in:
- lib/celluloid/io/tcp_socket.rb
Overview
TCPSocket with combined blocking and evented support
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.
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 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 |
# File 'lib/celluloid/io/tcp_socket.rb', line 35 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
28 29 30 |
# File 'lib/celluloid/io/tcp_socket.rb', line 28 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 |
# File 'lib/celluloid/io/tcp_socket.rb', line 15 def self.open(*args, &block) sock = new(*args) return sock unless block_given? begin yield(sock) ensure sock.close end end |
Instance Method Details
#recv(maxlen, flags = nil) ⇒ Object
Receives a message
101 102 103 104 |
# File 'lib/celluloid/io/tcp_socket.rb', line 101 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
107 108 109 110 111 |
# File 'lib/celluloid/io/tcp_socket.rb', line 107 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
96 97 98 |
# File 'lib/celluloid/io/tcp_socket.rb', line 96 def to_io @socket end |