¿Cómo configuro el tiempo de espera del socket en Ruby?
network-programming (3)
Creo que el enfoque de no bloqueo es el camino a seguir.
Probé el artículo mencionado anteriormente y aún así pude colgarlo.
este artículo que no bloquea las redes y el enfoque anterior de jonke me llevaron por el camino correcto. Mi servidor estaba bloqueando en la conexión inicial, así que necesitaba que fuera un nivel un poco más bajo.
el socket rdoc puede dar más detalles en connect_nonblock
def self.open(host, port, timeout=10)
addr = Socket.getaddrinfo(host, nil)
sock = Socket.new(Socket.const_get(addr[0][0]), Socket::SOCK_STREAM, 0)
begin
sock.connect_nonblock(Socket.pack_sockaddr_in(port, addr[0][3]))
rescue Errno::EINPROGRESS
resp = IO.select([sock],nil, nil, timeout.to_i)
if resp.nil?
raise Errno::ECONNREFUSED
end
begin
sock.connect_nonblock(Socket.pack_sockaddr_in(port, addr[0][3]))
rescue Errno::EISCONN
end
end
sock
end
para obtener una buena prueba. iniciar un servidor de socket simple y luego hacer un ctrl-z para fondo
IO.select espera que los datos entren en la secuencia de entrada en 10 segundos. esto puede no funcionar si ese no es el caso.
Debería ser un buen reemplazo para el método abierto de TCPSocket.
¿Cómo se configura el tiempo de espera para bloquear operaciones en un socket Ruby?
El objeto de tiempo de espera es una buena solución.
Este es un ejemplo de E / S asíncrona (de naturaleza no bloqueante y se produce de forma asíncrona al flujo de la aplicación).
IO.select(read_array
[, write_array
[, error_array
[, timeout]]] ) => array or nil
Puede usarse para obtener el mismo efecto.
require ''socket''
strmSock1 = TCPSocket::new( "www.dn.se", 80 )
strmSock2 = TCPSocket::new( "www.svd.se", 80 )
# Block until one or more events are received
#result = select( [strmSock1, strmSock2, STDIN], nil, nil )
timeout=5
timeout=100
result = select( [strmSock1, strmSock2], nil, nil,timeout )
puts result.inspect
if result
for inp in result[0]
if inp == strmSock1 then
# data avail on strmSock1
puts "data avail on strmSock1"
elsif inp == strmSock2 then
# data avail on strmSock2
puts "data avail on strmSock2"
elsif inp == STDIN
# data avail on STDIN
puts "data avail on STDIN"
end
end
end
La solución que encontré que parece funcionar es usar Timeout :: timeout :
require ''timeout''
...
begin
timeout(5) do
message, client_address = some_socket.recvfrom(1024)
end
rescue Timeout::Error
puts "Timed out!"
end