Ruby 如何使用EventMachine在循环内与客户机对话?

Ruby 如何使用EventMachine在循环内与客户机对话?,ruby,websocket,eventmachine,em-websocket,Ruby,Websocket,Eventmachine,Em Websocket,我想在一个网站上实时显示我的程序的进度(这里以循环为例) 如果我有一个正常运行的Ruby服务器,客户端应该能够使用浏览器通过WebSocket连接到服务器,并且在连接后,实时接收有关新生成的进程的“更新”。无需轮询或Ajax 我测试这一点的想法是使用客户端JavaScript在EventMachine::WebSocket和客户端浏览器之间建立双工通信。 构建循环,并将更新发送到浏览器客户端 ruby_socket_server.rb: require 'eventmachine' requir

我想在一个网站上实时显示我的程序的进度(这里以循环为例)

如果我有一个正常运行的Ruby服务器,客户端应该能够使用浏览器通过WebSocket连接到服务器,并且在连接后,实时接收有关新生成的进程的“更新”。无需轮询或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
我希望它看起来像:

  • 服务器:我在循环1上
  • 客户端:刚刚收到循环1的通知
  • 服务器:我在环路2上
  • 客户端:刚刚收到循环2的通知
实际发生的情况:

  • 服务器:我在循环1上
  • 服务器:我在环路2上
  • 客户端:刚刚收到循环1的通知
  • 客户端:刚刚收到循环2的通知
我无法从Ruby循环中向客户机发送数据,也就是说,它最终会发送所有数据包,但不是像预期的那样在每次迭代中发送数据包。相反,它会等待服务器循环完成,并背靠背发送多个调用


我做错了什么?我正在寻找的是可能的吗?任何关于如何破解这个螺母的想法都会很有帮助。

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

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

使用Rails5.0,您可以使用与WebSocket具有良好兼容性的工具。

使用Rails5.0,您可以使用与WebSocket具有良好兼容性的工具。

谢谢!!就像一种魅力。@Pandem1c-酷。记住也要接受答案,这样人们就知道什么是有效的(点击左边的复选标记)。谢谢,谢谢!!就像一种魅力。@Pandem1c-酷。记住也要接受答案,这样人们就知道什么是有效的(点击左边的复选标记)。谢谢