【问题标题】:Ruby Thread with "watchdog"带有“看门狗”的 Ruby 线程
【发布时间】:2012-04-19 19:50:42
【问题描述】:

我正在实现一个 ruby​​ 服务器来处理从 GPRS 模块创建的套接字。问题是当模块掉电时,没有迹象表明插座已关闭。

我正在使用线程来处理同一服务器的多个套接字。我要问的是:有没有办法在线程内使用计时器,在每次套接字输入后重置它,如果它达到超时,关闭线程?我在哪里可以找到有关此的更多信息?

编辑:未检测到套接字关闭的代码示例

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 

【问题讨论】:

  • 使用eventmachine!因为它是♥。
  • 在这种情况下事件机器将如何提供帮助?
  • 您无法真正判断套接字已关闭。可能需要数小时、数天甚至数月,您的应用程序才会注意到套接字已关闭。您需要在客户端(GPRS 模块)和您的服务器之间进行 ping-bong。
  • 为什么事件机是一个不错的选择,因为它可以让您将所有这些网络逻辑与应用程序逻辑分开。现在,您可能仍然需要使用事件机实现乒乓机制(但是,我认为 EM 有心跳机制,但我觉得它不可靠),但它会允许更大的并发性并且它在尝试制作异步服务器时将为您省去很多麻烦!
  • 而且 EventMachine 是一个反应器模式架构,所以它本质上类似于 node.js,但更好(更好只是因为我是 Ruby 至上主义者)。

标签: ruby multithreading sockets io


【解决方案1】:

我认为你需要一个心跳机制。

【讨论】:

    【解决方案2】:

    猜测一下,您的套接字莫名其妙地关闭了,因为您没有捕获远程端关闭它们时引发的异常。

    您需要将连接处理程序包装在异常捕获块中。

    在不知道您使用的是什么模块/模型的情况下,我只会捏造它并说您有一个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
    

    这将捕获所有异常并将它们转储到带有堆栈跟踪的 stderr。从那里您可以看到导致它们的原因,并可能在其他地方更优雅地处理它们。

    【讨论】:

    • 我在来这里之前尝试过...但无济于事...套接字似乎没有关闭...
    【解决方案3】:

    只需检查标准 API 超时:

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

    【讨论】:

      猜你喜欢
      • 2011-12-04
      • 1970-01-01
      • 1970-01-01
      • 2018-12-24
      • 1970-01-01
      • 1970-01-01
      • 2016-08-21
      • 2013-09-21
      • 1970-01-01
      相关资源
      最近更新 更多