編集
AnyTermとの統合を検討する必要があります。次に、たとえば Apache を介して AnyTerm を直接公開するかmod_proxy
、Rails コントローラーをリバース プロキシとして機能させることができます (認証/セッションの検証を処理し、 controller.request
Cookie を除いてに再生しlocalhost:<AnyTerm-daemon-port>
、AnyTerm の応答として応答として送り返します)。
class ConsoleController < ApplicationController
# AnyTerm speaks via HTTP POST only
def update
# validate session
...
# forward request to AnyTerm
response = Net::HTTP.post_form(URI.parse('http://localhost:#{AnyTermPort}/', request.params))
headers['Content-Type'] = response['Content-Type']
render_text response.body, response.status
end
それ以外の場合は、IO::SelectまたはIO::read_noblockを使用して、(ネットワークまたはサブプロセスから) データをいつ読み取れるかを知る必要があるため、デッドロックは発生しません。こちらもご覧ください。また、Rails がマルチスレッド環境で使用されているか、 Ruby バージョンがこの IO::Select バグの影響を受けていないかを確認してください。
次の行に沿って何かを始めることができます。
status = POpen4::popen4("ping localhost") do |stdout, stderr, stdin, pid|
puts "PID #{pid}"
# our buffers
stdout_lines=""
stderr_lines=""
begin
loop do
# check whether stdout, stderr or both are
# ready to be read from without blocking
IO.select([stdout,stderr]).flatten.compact.each { |io|
# stdout, if ready, goes to stdout_lines
stdout_lines += io.readpartial(1024) if io.fileno == stdout.fileno
# stderr, if ready, goes to stdout_lines
stderr_lines += io.readpartial(1024) if io.fileno == stderr.fileno
}
break if stdout.closed? && stderr.closed?
# if we acumulated any complete lines (\n-terminated)
# in either stdout/err_lines, output them now
stdout_lines.sub!(/.*\n/m) { puts $& ; '' }
stderr_lines.sub!(/.*\n/m) { puts $& ; '' }
end
rescue EOFError
puts "Done"
end
end
も処理するstdin
には、次のように変更します。
IO.select([stdout,stderr],[stdin]).flatten.compact.each { |io|
# program ready to get stdin? do we have anything for it?
if io.fileno == stdin.fileno && <got data from client?>
<write a small chunk from client to stdin>
end
# stdout, if ready, goes to stdout_lines