2016-12-25 4 views
2

Это серверный веб-клиент. Я пытаюсь получить пользовательский ввод в цикле, а затем отправить его как сообщение 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. Но я надеялся, что есть более простой способ.

ответ

0

Он закончил работать, чтобы положить нить внутри цикла клеща:

EM.tick_loop do 
    Thread.new { 
     inp = gets.chomp 
     Ws.send inp 
    } 
    end.on_stop { EM.stop } 
Смежные вопросы