我想在网站上实时显示我的节目进度(这里以循环方式示例)。
如果我运行了正确的Ruby服务器,客户端应该能够使用浏览器通过websockets连接到服务器,并且一旦连接,就会实时接收关于新生成的进程的“更新”。不需要轮询,也不需要Ajax。
我对此进行测试的想法是使用客户端JavaScript在EventMachine :: WebSocket和客户端浏览器之间建立双工通信。 构建一个循环,并将更新发送到浏览器客户端。
ruby_socket_server.rb:
require 'eventmachine'
require 'em-websocket'
@sockets = []
EventMachine.run do
EventMachine::WebSocket.start(:host =>'localhost',:port =>8887) do |socket|
socket.onopen do
@sockets << socket
(0..10).each do |i|
puts "i am on loop #{i}" #to terminal window
@sockets.each do |s|
s.send "Just received notification of loop #{i}"
sleep(1) #pause for a second
end
end
end
end
main.js:
socket = new WebSocket('ws://localhost:8887');
socket.onopen = function(){
console.log('OPEN');
}
socket.onclose = function(){
console.log('CLOSED');
}
socket.onmessage = function(msg){
console.log(msg);
}
我希望它看起来像:
实际发生了什么:
我无法从WITHIN的Ruby循环向客户端发送数据,即它最终发送所有数据包,但不会按预期在每次迭代期间发送。相反,它会一直等到服务器循环完成,然后重新发送多个调用。
我在这里做错了什么?我正在寻找甚至可能吗?关于如何破解这个坚果的任何想法都会有所帮助。
答案 0 :(得分:1)
EventMachine不是多线程的。因此,如果你不让它运行,即如果你留在任何回调中,那么什么都不会发生。
在您的示例中,您在回调中调用sleep
。这将阻止回调退出,因此EM无法运行,如果无法运行,则无法发送消息。
因此,任何EM服务器都必须完全围绕一个规范的回调设置构建。
这就是为什么它被称为事件机器。它需要一种稍微不同的思维方式,但是一旦掌握了它,你应该没事。
以下是有关如何使其发挥作用的示例:
EM.run do
EM::WebSocket.start(:host =>'localhost',:port =>8887) do |ws|
ws.onopen { |handshake|
puts "New connection from #{handshake.origin}"
loop = 1
timer = EM.add_periodic_timer(1) {
ws.send "Timer loop #{loop}"
if (loop += 1) == 5
EM.cancel_timer(timer)
ws.send "Bye"
ws.close_websocket
end
}
}
end
end
答案 1 :(得分:0)
使用Rails5.0,您可以使用与WebSockets具有良好兼容性的ActionCable。