lib/ionian/socket.rb in ionian-0.6.10 vs lib/ionian/socket.rb in ionian-0.6.11

- old
+ new

@@ -38,10 +38,13 @@ # # @option kwargs [:tcp, :udp, :unix] :protocol (:tcp) Type of socket to create. # :udp will be automatically selected for addresses in the multicast # range, or if the broadcast flag is set. # + # @option kwargs [Fixnum] :connect_timeout (nil) Number of seconds to wait + # when connecting before timing out. Raises Errno::EHOSTUNREACH. + # # @option kwargs [Boolean] :persistent (true) The socket remains open after # data is sent if this is true. The socket closes after data is sent and # a packet is received if this is false. # # @option kwargs [Boolean] :bind_port (:port) Local UDP port to bind to for @@ -106,15 +109,16 @@ else # Initialize new socket. # Parse host out of "host:port" if specified. - host_port_ary = kwargs.fetch(:host).to_s.split ':' + host_port_array = kwargs.fetch(:host).to_s.split ':' - @host = host_port_ary[0] - @port = kwargs.fetch :port, host_port_ary[1].to_i || 23 + @host = host_port_array[0] + @port = kwargs.fetch :port, (host_port_array[1] || 23).to_i @bind_port = kwargs.fetch :bind_port, @port + @connect_timeout = kwargs.fetch :connect_timeout, nil @broadcast = kwargs.fetch :broadcast, false # Automatically select UDP for the multicast range. Otherwise default to TCP. default_protocol = :tcp @@ -273,49 +277,55 @@ # Initialize or reinitialize @socket. def create_socket @socket.close if @socket and not @socket.closed? - case @protocol - when :tcp - @socket = ::TCPSocket.new @host, @port - @socket.extend Ionian::Extension::Socket - - @socket.no_delay = @no_delay - # Windows complains at SO_CORK, so only set it if it was specified. - @socket.cork = @cork if @cork - - when :udp - @socket = ::UDPSocket.new - @socket.extend Ionian::Extension::Socket - - @socket.reuse_addr = true if - @reuse_addr or - @broadcast or - Ionian::Extension::Socket.multicast? @host + begin + Timeout.timeout(@connect_timeout) do + case @protocol + when :tcp + @socket = ::TCPSocket.new @host, @port + @socket.extend Ionian::Extension::Socket + + @socket.no_delay = @no_delay + # Windows complains at SO_CORK, so only set it if it was specified. + @socket.cork = @cork if @cork + + when :udp + @socket = ::UDPSocket.new + @socket.extend Ionian::Extension::Socket + + @socket.reuse_addr = true if + @reuse_addr or + @broadcast or + Ionian::Extension::Socket.multicast? @host + + @socket.broadcast = true if @broadcast + + @socket.bind ::Socket::INADDR_ANY, @bind_port + @socket.connect @host, @port + + @socket.ip_add_membership if Ionian::Extension::Socket.multicast? @host + + when :unix + @socket = ::UNIXSocket.new @host + @socket.extend Ionian::Extension::Socket + + end - @socket.broadcast = true if @broadcast - - @socket.bind ::Socket::INADDR_ANY, @bind_port - @socket.connect @host, @port - - @socket.ip_add_membership if Ionian::Extension::Socket.multicast? @host - - when :unix - @socket = ::UNIXSocket.new @host - @socket.extend Ionian::Extension::Socket - + # Windows complains at SO_LINGER, so only set it if it was specified. + @socket.linger = @linger if @linger + + @socket.expression = @expression if @expression + + # Register listeners. + @ionian_listeners.each { |proc| @socket.on_match &proc } + + initialize_socket_methods + end + rescue Timeout::Error + raise Errno::EHOSTUNREACH end - - # Windows complains at SO_LINGER, so only set it if it was specified. - @socket.linger = @linger if @linger - - @socket.expression = @expression if @expression - - # Register listeners. - @ionian_listeners.each { |proc| @socket.on_match &proc } - - initialize_socket_methods end # Expose the @socket methods that haven't been defined by this class. # Only do this once for performance -- when non-persistent sockets are # recreated, they should be of the same type of socket. \ No newline at end of file