Это серверный веб-клиент. Я пытаюсь получить пользовательский ввод в цикле, а затем отправить его как сообщение websocket на сервер. Основные действия работают, и я могу ping/pong сервер. Но это не работает, чтобы поместить петлю в функции WebSocket on(:open)
:looping попадает в Eventmachine/faye websocket
Client (выдержка):
require 'faye/websocket'
require 'eventmachine'
EM.run do
ws = Faye::WebSocket::Client.new('ws://localhost:3000/')
ws.on :message do |event|
puts event.data
end
ws.on :open do |event|
ws.send "predefined" # this works
ws.send gets.chomp # this does too
loop { ws.send gets.chomp } # this does not
end
end
сервера (отрывок), который, кажется, работает нормально:
def self.onmessage(request, ws, msg)
EM.next_tick { Sockets.each{|s| s.send msg.data } }
end
Я думаю, проблема заключается в том, что цикл блокирует функцию on(:open)
от возврата и перемещения машины событий к следующему тику.
я могу разблокировать машину событий с помощью TickLoop:
def start_tick_loop
EM.tick_loop do
Ws.send gets.chomp
end.on_stop { EM.stop }
end
EM.run {
Ws.on :open do |event|
start_tick_loop
end
}
, но это не является идеальным, поскольку каждый клиент заблокирован gets.chomp
. Я хочу, чтобы пользовательский ввод не блокировал обработчик on(:message)
.
В конце дня я предполагаю, что могу создать сценарий оболочки, который следит за файлом за изменениями и отправляет вывод gets.chomp
. Но я надеялся, что есть более простой способ.