Sha256: 53062573c8aecb71052b417ac072872eaa345bbf5f642c7cd86121231ca81b5f
Contents?: true
Size: 1.95 KB
Versions: 3
Compression:
Stored size: 1.95 KB
Contents
# frozen_string_literal: true require 'socket' require 'timeout' module Sip2 # # Sip2 Non-blocking socket # From https://spin.atomicobject.com/2013/09/30/socket-connection-timeout-ruby/ # class NonBlockingSocket < Socket DEFAULT_TIMEOUT = 5 attr_accessor :connection_timeout # rubocop:disable Metrics/AbcSize, Metrics/MethodLength def self.connect(host:, port:, timeout: DEFAULT_TIMEOUT) # Convert the passed host into structures the non-blocking calls can deal with addr = Socket.getaddrinfo(host, nil) sockaddr = Socket.pack_sockaddr_in(port, addr[0][3]) NonBlockingSocket.new(Socket.const_get(addr[0][0]), Socket::SOCK_STREAM, 0).tap do |socket| socket.setsockopt(Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1) socket.connection_timeout = timeout begin # Initiate the socket connection in the background. If it doesn't fail # immediately it will raise an IO::WaitWritable (Errno::EINPROGRESS) # indicating the connection is in progress. socket.connect_nonblock(sockaddr) rescue IO::WaitWritable # IO.select will block until the socket is writable or the timeout # is exceeded - whichever comes first. if IO.select(nil, [socket], nil, timeout) begin # Verify there is now a good connection socket.connect_nonblock(sockaddr) rescue Errno::EISCONN # Good news everybody, the socket is connected! rescue StandardError # An unexpected exception was raised - the connection is no good. socket.close raise end else # IO.select returns nil when the socket is not ready before timeout # seconds have elapsed socket.close raise ConnectionTimeout end end end end # rubocop:enable Metrics/AbcSize, Metrics/MethodLength end end
Version data entries
3 entries across 3 versions & 1 rubygems
Version | Path |
---|---|
sip2-0.2.3 | lib/sip2/non_blocking_socket.rb |
sip2-0.2.2 | lib/sip2/non_blocking_socket.rb |
sip2-0.2.1 | lib/sip2/non_blocking_socket.rb |