【问题标题】:Synchronizing PTY output with Eventmachine将 PTY 输出与 Eventmachine 同步
【发布时间】:2012-10-20 10:34:25
【问题描述】:

我正在尝试使用 ruby​​ 1.9.3 的 PTY 和 io/console 模块编写 EventMachine 服务器以通过 telnet 或 ssh 运行 nCurses 应用程序:

require 'rubygems'
require 'socket'
require 'pty'
require 'io/console'
require 'eventmachine'

 module CursesServer
   def post_init
     puts "-- someone connected to the server!"
     @reader, @writer, @pid = PTY.spawn('ruby ./ncurses_app_to_run.rb')
     @reader.sync = true #No buffering stdout     
  end

   def receive_data(data)
     screen = @reader.read(<number_of_bytes>)
     puts "received: " + data # Log input on server side
     send_data screen
     close_connection if data =~ /quit/i
   end

   def unbind
     puts "-- someone disconnected from the server!"
  end
end

# Note that this will block current thread.
EventMachine.run {
  EventMachine.start_server "127.0.0.1", 8081, CursesServer
}

如果我使用传递给@reader.read 的参数值,我可以让部分屏幕显示在客户端,但是我不知道如何确定客户端终端的实际大小,无论是最初还是在客户端调整终端大小之后。

如何使输出与客户端终端的大小同步?是否可以使用 telnet/netcat 或者我必须使用更强大的协议,如 ssh?

提前致谢。

【问题讨论】:

    标签: ruby terminal eventmachine curses pty


    【解决方案1】:

    也许这可以帮助你。不过,我正在使用 EventMachine 和 ZeroMQ,但它似乎很容易适应。

    def run_command command
        _start = Time.now
        begin
          PTY.spawn( command ) do |r, w, pid|
            r.sync = true
            begin
              r.each do |line|
                $announce_socket.send_msg "LOG:#{line}"
              end
           rescue => ex
            puts "ERROR: #{ex.message}"
           end
         end
        rescue PTY::ChildExited => e
          $announce_socket.send_msg "CMD_PREMATURE_EXIT:#{e.message}"
          puts "command exited prematurely, notified UI"
        end
        $announce_socket.send_msg "CMD_EXIT:#{Time.now - _start}"
        puts "done running commmand (took #{Time.now - _start} seconds)"
      end
    end
    

    还有反应堆部分:

    $context = EM::ZeroMQ::Context.new(1)
    
    def cleanup(exit_code = 0)
      EM::stop()
      exit exit_code
    end
    
    trap('INT') do
      cleanup
    end
    
    EM.run do
    
      $announce_socket = $context.socket ZMQ::DEALER, EMDEALERHandler.new
      $announce_socket.identity = MY_ID
      $announce_socket.connect "tcp://#{host_ip}:7777"
    
      # announce presence
      $announce_socket.send_msg "UP"
    end
    

    在这之后,你只需要一个 ROUTER 套接字来推送数据。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-07-29
      • 2012-11-19
      • 1970-01-01
      相关资源
      最近更新 更多