2012-04-06 3 views
1

Я реализую рубиновый сервер для обработки сокетов, создаваемых из модулей GPRS. Дело в том, что когда модуль отключается, нет никаких признаков того, что гнездо закрыто.Ruby Thread с «watchdog»

Я занимаюсь потоками для обработки нескольких сокетов с одним и тем же сервером. Я прошу следующее: есть ли способ использовать таймер внутри потока, перезагружать его после каждого входа сокета, и если он попадает в таймаут, закрывает поток? Где я могу найти дополнительную информацию об этом?

EDIT: Пример кода, который не обнаруживает сокет закрытия

require 'socket' 

server = TCPServer.open(41000) 
loop do 
    Thread.start(server.accept) do |client| 
     puts "Client connected" 

     begin 
      loop do 
       line = client.readline 

       open('log.txt', 'a') { |f| 
        f.puts line.strip 
       } 
      end 
     rescue 
      puts "Client disconnected" 
     end 
    end 
end 
+0

Используйте [eventmachine] (https://github.com/eventmachine/eventmachine)! Потому что это ♥. – omninonsense

+0

Как в этом случае поможет машина-машина? –

+0

Вы не можете сказать, что розетка закрыта. Это может занять несколько часов, дней и, возможно, месяцев, пока ваше приложение не сообщит, что розетка закрыта. Вам нужно использовать ping-bong между клиентом (GPRS-модуль) и вашим сервером. – omninonsense

ответ

1

Я думаю, вам нужен механизм сердцебиения.

+0

Не могли бы вы объяснить дальше? –

0

Угадайте, что ваши сокеты неудержимо закрываются, потому что вы не перехватываете исключения, которые возникают, когда они закрываются удаленным концом.

необходимо обернуть обработчик подключений в блок блокировки исключений.

Не зная, какой модуль/модель вы используете, я буду просто подталкивать ее и сказать, что у вас есть процедура process_connection. Так что вам нужно сделать что-то вроде этого:

def process_connection(conn) 
    begin 
     # do stuff 
    rescue Exception => e 
     STDERR.print "Caught exception #{e}: #{e.message}\n#{e.backtrace}\n" 
    ensure 
     conn.close 
    end 
end 

Это будет перехватывать все исключения и сбрасывать их в стандартный вывод с трассировки стека. Оттуда вы можете видеть, что их вызывает, и, возможно, обрабатывать их более изящно в другом месте.

+0

Я попробовал это, прежде чем приходить сюда ... но безрезультатно ... сокет не кажется закрытым ... –

+0

, тогда я не могу догадаться. Пожалуйста, покажите код. –

0

Просто проверьте STANDAR API Timeout:

require 'timeout' 
status = Timeout::timeout(3){sleep(1)} 
puts status.inspect 
status = Timeout::timeout(1){sleep(2)}