在ruby套接字上实现超时的最佳方式



我只是一个机械工程师(编程新手)开发一个用于监控客户太阳能系统输出功率的web应用程序。我目前正试图实现脚本我的应用程序使用打开一个套接字连接,并使用超时和线程查询客户逆变器。目前,该脚本(通过cron设置为每15分钟运行一次)非常琐碎,看起来像这样:

System.all.each do |system|
  @sock = TCPSocket.open(system.ip,51101)
  @query = "x0Ax05x03x00xB5x00x01x94x68x0D"
  @sock.write(@query)      
  @s = @sock.read(9)
  # do stuff with @s
  @sock.close
end

我想在其他任何事情之前解决的一个大问题:每天日落之后,当所有客户逆变器关闭当天,该脚本尝试其第一个套接字。写/读,我认为它"挂起",因为为了让它重新开始连接和查询,我必须在早上重新启动我的电脑。所以我想在套接字本身和套接字上都正确地实现超时。阅读以避免这种情况发生。从我到目前为止所做的堆栈溢出研究来看,我认为也许我应该做下面的事情来做与上面相同的事情,但是使用一个在2秒后超时的套接字:

@port = 51101
System.all.each do |system|
  @sock = Socket.new(Socket::AF_INET, Socket::SOCK_STREAM, 0)
  @sock_address = Socket.sockaddr_in(@port, system.ip)
  begin
    @sock.connect_nonblock(@sock_address)
    @query = "x0Ax05x03x00xB5x00x01x94x68x0D"
    @sock.write(@query)      
    @s = @sock.read(9)
    # do stuff with @s
    @sock.close
  rescue Errno::EINPROGRESS
    if IO.select(nil, [@sock], nil, 2)
      begin
        @sock.connect_nonblock(@sock_address)
        @query = "x0Ax05x03x00xB5x00x01x94x68x0D"
        @sock.write(@query)      
        @s = @sock.read(9)
        # do stuff with @s
        @sock.close
      rescue Errno::ECONNREFUSED, Errno::EHOSTUNREACH
        # do something
      end
    end
  end
end

但是对于这段代码,我有很多不明白的地方。首先,Errno::EINPROGRESS是什么时候引发的?第二个@sock.connect_nonblock(@sock_address)是否出现在第6行,因为如果系统已经尝试了"太长时间"但不超过2秒,该代码将重试连接?另外,从我读到的Errno::EINPROGRESS似乎是Windows的东西。Mac OS的等效是什么?或者这些问题可能完全无关紧要。无论走哪条路,请让我知道我是否走对了方向。或者,如果你能提供给我一个注释片段演示正确的方法来做到这一点。

其次,如果套接字连接正常,我如何实现套接字的超时?阅读,使它不会使一切悬挂(这是我认为实际上是发生当逆变器关闭)?我一直读到ruby超时。不应该使用Rb。我怎么能使它只尝试阅读几秒钟,然后关闭插座,如果它挂起?非常感谢。

从我现在的理解,这是最简单的(不一定是最好的-取决于您的需要)只是为了避免这个问题,试图让我的套接字连接尝试超时以及我的套接字。阅读时间到。因为我的脚本很简单,我使用Ruby 1.8.7,我使用的是system_timer gem (Ruby的超时库对Ruby 1.8不可靠)。在Ruby 1.8.x中,system_timer解决了超时问题。

http://systemtimer.rubyforge.org/

文档很好

相关内容

  • 没有找到相关文章

最新更新