提问人:Jens Schmidt 提问时间:7/6/2012 更新时间:7/6/2012 访问量:141
在Ruby on Rails中查找对象(需要在Net::SSH中取消ssh连接)
Finding Object in Ruby on Rails (need to cancel ssh connection in Net::SSH)
问:
我使用 Net::SSH 创建了以下端口转发:
def connectToCustomerSystem
Net::SSH.start("localhost", 'myuser', :password => "password") do |ssh|
logger.debug ssh.exec!("hostname")
ssh.forward.local(1234, "www.capify.org", 80)
#ssh.loop { true } #dont use loop to directly render director/index
end
render :controller => "director", :action => "index"
end
现在,我将以一种新的其他方法通过“ssh.forward.cancel_local(1234)”取消此连接。
def disconnectForwarding
ssh.forward.cancel_local(1234)
end
但是,当然,“ssh”在这种情况下是无效的。如何搜索类型为“Net::SSH”的所有可用对象?或者有没有其他方法可以让我退出特定的转发(因为最终,一些不同的用户会有很多转发,我不想杀死所有用户,只是一个特定的转发)。
提前致谢。
答:
0赞
ebeland
7/6/2012
#1
我看到你试图在与 Rails 交互时保留有状态的 Ruby 对象。这与 Rails 对服务器的“不共享”方法不相符。由于块超出了方法的范围,ssh 不仅不在范围内,而且下次还将与不同的工作进程进行通信。
您需要在后台单独运行时间较长的 ruby 进程来管理 ssh 连接。执行此操作的一种简单方法是启动 ruby 脚本并使用 DRb 连接到管理 ssh 的对象。然后,您可以重新连接到 Ruby 进程,在每次处理请求时管理连接,并通过 DRb 向其发出命令。在这种情况下,ssh 变量可能用作您通过 DRb 与之交谈的对象中的实例变量(看起来您可以将其设置为循环,以便它一直存在)。
有一些可怕的方法可以摆脱作用域框,例如将变量设置为线程局部变量,或搜索ObjectSpace.each_object,但这些方法原则上非常糟糕。
评论
0赞
Jens Schmidt
7/6/2012
你好!感谢您的回答。但是在 Ruby 中,我想我会遇到同样的问题 - 如果我使用一个 ruby 脚本进行几个 SSH 连接。一种将运行 SSH 进程的方法(没有“ssh.loop”,否则 SSH 进程和整个 ruby 脚本将无法完成)。但是,如果我为每个 SSH 连接创建一个 ruby 脚本 (DRb),我最终会遇到开放 tcp 端口的问题,我也没有(我认为我需要每个新脚本中的“URI=”druby://localhost:8787“”,这意味着我需要每个 SSH 连接两个端口,因为你知道我的意思)?
0赞
ebeland
7/6/2012
您计划将其扩展到您认为会用完 tcp 端口的程度吗?DRb 具有可伸缩性限制。如果您拍摄> 50 个同时连接,DRb 将导致问题。在这种情况下,我会看看 dcell github.com/celluloid/dcell。就脚本完成而言,如果通过调用方法将其关闭,则对象可能具有一个实例变量@stop该变量可以关闭操作。您可以将其传递到 loop 方法中,该方法采用一个可选块,当该块为 true 时,该块将停止处理。多个进程可以连接到单个端口上的一个 DRB 服务器。
0赞
ebeland
7/6/2012
实际上,我有那句话。当块为 false 时,它会停止它,所以可以将其命名为 @active 或类似的东西。
评论