EventMachine如何在keypress上编写键盘处理程序

Ch4*_*Ass 3 ruby eventmachine

我使用EventMachine LineText2协议,我想receive_line每次按下键盘上的字符而不是在我输入新行时触发方法.有没有办法改变默认行为?

class KeyboardHandler < EM::Connection
  include EM::Protocols::LineText2

  def initialize(q)
    @queue = q
  end

  def receive_line(data)
    @queue.push(data)
  end
end

EM.run {
  q = EM::Queue.new

  callback = Proc.new do |line|
    # puts on every keypress not on "\n"
    puts line
    q.pop(&callback)
  end
  q.pop(&callback)

  EM.open_keyboard(KeyboardHandler, q)
}
Run Code Online (Sandbox Code Playgroud)

jmk*_*yes 5

如果要从终端接收无缓冲输入,则应在标准输入上关闭规范模式.(我还关闭了echo以使屏幕更易于阅读.)在代码调用之前#open_keyboard或在处理程序初始化程序中添加:

require 'termios'
# ...
attributes = Termios.tcgetattr($stdin).dup
attributes.lflag &= ~Termios::ECHO # Optional.
attributes.lflag &= ~Termios::ICANON
Termios::tcsetattr($stdin, Termios::TCSANOW, attributes)
Run Code Online (Sandbox Code Playgroud)

例如:

require 'termios'
require 'eventmachine'

module UnbufferedKeyboardHandler
  def receive_data(buffer)
    puts ">>> #{buffer}"
  end
end

EM.run do
  attributes = Termios.tcgetattr($stdin).dup
  attributes.lflag &= ~Termios::ECHO
  attributes.lflag &= ~Termios::ICANON
  Termios::tcsetattr($stdin, Termios::TCSANOW, attributes)

  EM.open_keyboard(UnbufferedKeyboardHandler)
end
Run Code Online (Sandbox Code Playgroud)