У меня есть рубиновый сценарий, который одновременно и асинхронно получает и отображает сообщения с сервера и позволяет ввод данных пользователем на консоли. Когда сообщение получено, оно в настоящее время пишется посреди того, что вводит пользователь. Сам вход не искажен, но это выглядит ужасным. Идеально, это сохранило бы пользователей текущий вход, произвело бы сообщение и затем восстановило бы вход на следующей строке. Я сделал это в c путем прерывания каждого нажатия клавиши, но все, что я помню, - то, что это была главная стычка. Я довольно плохо знаком с рубином, таким образом, я не уверен, существует ли хороший способ сделать это, или как сделать это.
Пример: Пользователь вводит >abcde
, и сообщение hello
входит, и пользовательские типы fgh
после. Консоль теперь показала бы:
>abcdehellofgh
и пользователь может продолжить вводить в конце. Я хотел бы, чтобы это показало:
hello
>abcdefgh
Две важные части моего предложения:
1. system ("stty raw -echo") # для мгновенного получения любого набранного символа в сочетании с
2. используя STDIN.getc со строкой-var, служащей буфером ввода, для повторной печати пользовательского ввода.
Нажатие 9 (& логическая переменная incoming_message) используется для сверхпростой симуляции ваших серверных сообщений.
(Если быть более реалистичным, пример раздувается, не добавляя ничего особенного, поскольку вам все равно придется адаптировать идею к вашему сценарию.)
Нажмите x для выхода.
Пример вывода:
$ ruby simultaneous_input_and_output.rb
Hello World!9
The incoming message is: true
Hello World!9x
You entered:
Hello World!9x
End!
#!/usr/bin/ruby
$input_buffer = "";
incoming_message = false
begin
system("stty raw -echo")
begin
str = STDIN.getc
print str.chr
$input_buffer = $input_buffer + str.chr
if str.chr == '9'
incoming_message = true
end
if incoming_message
puts "\nThe incoming message is: " + incoming_message.to_s
print $input_buffer
incoming_message = false
end
end while (str.chr != 'x')
ensure
system("stty -raw echo")
end
puts "\n\nYou entered:"
puts $input_buffer
puts "End!"
PS: для системы ("stty raw -echo") см. (Пользователь Джей) Как получить один символ без нажатия клавиши ввода?
Я столкнусь почти с той же проблемой.
Я решил изменить свой подход. Я собираюсь написать простой клиент с полем ввода текста внизу и окном сообщений для остальной части экрана.
Клиент и сервер будут обмениваться данными, используя какой-то формат сообщений - возможно, YAML, поскольку он так хорошо работает с Ruby, но может быть что-то значительно более простое.
(Однако я не уверен, что это точный ответ на ваш вопрос.)