Wie stelle ich das Socket-Timeout in Ruby?
-
04-07-2019 - |
Frage
Wie stellen Sie den Timeout für den Betrieb auf einem Ruby-Buchse blockiert?
Lösung
Die Lösung, die ich gefunden, die zu funktionieren scheint benutzen Timeout :: Timeout :
require 'timeout'
...
begin
timeout(5) do
message, client_address = some_socket.recvfrom(1024)
end
rescue Timeout::Error
puts "Timed out!"
end
Andere Tipps
Das Timeout-Objekt ist eine gute Lösung.
Dies ist ein Beispiel von asynchronen I / O (in der Natur nicht blockierenden und tritt asynchron der Ablauf der Anwendung.)
IO.select(read_array
[, write_array
[, error_array
[, timeout]]] ) => array or nil
Kann verwendet werden, um den gleichen Effekt zu erzielen.
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
Ich denke, die nicht blockierende Ansatz ist der Weg zu gehen.
Ich habe versucht, die oben genannten Artikel erwähnt und konnte immer noch bekommen es zu hängen.
dieser Artikel nicht blockierende Vernetzung und der Jonkes Ansatz hat mich oben auf dem richtigen Weg. Mein Server blockiert wurde auf dem anfänglichen verbinden, so brauchte ich es eine wenig niedrige Ebene.
die Buchse rdoc können mehr Details in den connect_nonblock geben
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
einen guten Test zu erhalten. Inbetriebnahme eines einfachen Socket-Server und dann eine Strg-Z auf Hintergrund it
die IO.select wird Daten erwartet innerhalb von 10 Sekunden auf dem Eingangsstrom zu kommen. Dies kann nicht funktionieren, wenn dies nicht der Fall ist.
Es sollte ein guter Ersatz für die TCPSocket offene Methode.