1

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」の利用可能なすべてのオブジェクトを検索するにはどうすればよいですか?または、特定の転送を終了する方法は他にありますか(最終的には、一部の異なるユーザーには多くの転送があり、特定のユーザーだけを殺したくないためです)。

前もって感謝します。

4

1 に答える 1

0

Rails とやり取りしながら、ステートフルな Ruby オブジェクトを維持しようとしているようですね。これは、Rails のサーバーに対する「何も共有しない」アプローチとはうまくいきません。ブロックがメソッドのスコープ外であるため、ssh がスコープ内にないだけでなく、次回は別のワーカー プロセスと通信することになります。

必要なのは、ssh 接続を管理するために、バックグラウンドで実行時間の長い別の Ruby プロセスです。これを行う簡単な方法は、Ruby スクリプトを起動し、DRb を使用して ssh を管理するオブジェクトに接続することです。その後、リクエストが処理されるたびに接続を管理する Ruby プロセスに再接続し、DRb 経由でコマンドを与えることができます。この場合、ssh 変数は、 DRbを介して話すオブジェクト内のインスタンス変数として機能する可能性があります(これをループするように設定して、くっつくように設定できるようです)。

変数をスレッドローカル変数として設定したり、ObjectSpace.each_object を検索したりするなど、スコープ ボックスから抜け出すための恐ろしいアプローチがいくつかありますが、それらのアプローチは原則としてかなり悪いものです。

于 2012-07-05T21:10:41.710 に答える