Посылайте многократные сообщения в websocket, используя темы
Я делаю сервер Ruby, используя гем em-websocket. Когда клиент отправляет какое-либо сообщение (например, "поток"), сервер создает два разных потока и параллельно отправляет клиенту два ответчика (на самом деле я изучаю многопоточность и веб-сокеты). Вот мой код:
EM.run {
EM::WebSocket.run(:host => "0.0.0.0", :port => 8080) do |ws|
ws.onmessage { |msg|
puts "Recieved message: #{msg}"
if msg == "thread"
threads = []
threads << a = Thread.new {
sleep(1)
puts "1"
ws.send("Message sent from thread 1")
}
threads << b = Thread.new{
sleep(2)
puts "2"
ws.send("Message sent from thread 2")
}
threads.each { |aThread| aThread.join }
end
Как это выполняется:
- Я отправляю сообщение "поток" на сервер
- Через одну секунду в моей консоли я вижу напечатанную строку "1". Еще через секунду я вижу "2".
- Только после этого оба сообщения одновременно отправляются клиенту.
Проблема в том, что я хочу отправлять сообщения точно в то же время, когда отправляются выходные данные отладки "1" и "2".
Моя версия Ruby 1.9.3p194.
2 ответа
У меня нет опыта работы с EM, так что возьмите это с щепоткой соли.
Однако, на первый взгляд, похоже, что "aThread.join" фактически блокирует завершение метода "onmessage" и, таким образом, также предотвращает обработку "ws.send". Вы пытались удалить блок "threads.each"?
Изменить: После того, как мы проверили это в Arch Linux с обоими ruby 1.9.3 и 2.0.0 (используя "test.html" из примеров em-websocket), я уверен, что даже если удалить блок "threads.each" не не решит проблему для вас, вам все равно придется удалить ее, так как Thread#join приостановит текущий поток до тех пор, пока не будут завершены "присоединенные" потоки.
Если вы выполните вызов функции "ws.onmessage" через исходный код, вы окажетесь в методе Connection # send_data модуля Eventmachine и найдете следующее в комментариях:
Вызовите этот метод для отправки данных на удаленный конец сетевого подключения. Он принимает один строковый аргумент, который может содержать двоичные данные. Данные буферизуются для отправки в конце этого тика цикла цикла (цикла).
Поскольку "onmessage" блокируется "join" до тех пор, пока не будут запущены оба метода "send", тик цикла обработки событий не может завершиться, пока оба набора данных не буферизуются, и, таким образом, все данные не могут быть отправлены до этого времени.
Если он по-прежнему не работает после удаления блока "threads.each", убедитесь, что вы перезапустили свою машину для обработки событий, и вместо этого попробуйте установить для второго режима ожидания значение 5 секунд. Я не знаю, сколько времени занимает типичный цикл обработки событий в Eventmachine (и я не могу представить, что он длится до секунды), однако документация в основном гласит, что если несколько вызовов "send" выполняются в одном тике Все они будут отправлены одновременно. Таким образом, увеличение разницы во времени будет гарантировать, что это не происходит.
Я думаю, что проблема заключается в том, что вы вызываете метод сна, передавая 1 в первый поток и 2 во второй поток. Попробуйте удалить спящий вызов в обоих потоках или передать одно и то же значение при каждом вызове.