【问题标题】:event machine websocket server: how to push periodic messages to client?事件机websocket服务器:如何将定期消息推送到客户端?
【发布时间】:2013-08-22 13:53:24
【问题描述】:

我想用ruby语言gem em-websocket: https://github.com/igrigorik/em-websocket 在 eventmachine 上运行 websocket 服务器。

我成功运行了 echo 服务器演示:

EM.run {
  EM::WebSocket.run(:host => "0.0.0.0", :port => 8080) do |ws|
    ws.onopen { |handshake|
      puts "WebSocket connection open"

      ws.send "Hello Client, you connected to #{handshake.path}"
    }

    ws.onclose { puts "Connection closed" }

    ws.onmessage { |msg|
      puts "Recieved message: #{msg}"
      ws.send "Pong: #{msg}"
    }
  end
}

现在我想开发一个演示,服务器可以通过 websocket 消息每隔 n 毫秒(随机值)将一些数据推送到连接的客户端......实际上类似于:

def periodic_push
    # random elapsed: from 100 milliseconds to 6 seconds
    msec_value =  (rand(100..6000) / 1000.0 )
    message = "time: #{Time.now} value: #{msec_value.to_s}"

    ws.send message
    puts message

    sleep (msec_value)
end

我知道我不能在 EM 循环中使用 sleep() 系统调用, 但我不知道如何在EM::WebSocket loop 中插入周期性事件; 也许是EventMachine::PeriodicTimer?怎么样?

有人可以帮我提供一个代码示例 chunck 吗? 谢谢! 乔治

【问题讨论】:

  • EM.add_periodic_timer(1){ puts "1 second passed" }

标签: ruby-on-rails ruby websocket eventmachine


【解决方案1】:

我自己找到了一个解决方案:在下面的代码中,服务器每 500 毫秒向客户端推送一条 websocket 消息。 ( PeriodicTimer.new(0.5) )。

我现在遇到的问题是如何动态重置计时​​器以每 N 毫秒发送一条消息,其中 N 是一个随机值...知道吗?

require 'eventmachine'
require 'em-websocket'
require 'socket'

EM.run {
  EM::WebSocket.run(:host => "0.0.0.0", :port => 8080) do |ws|

    ws.onopen { |handshake|
      puts "WebSocket connection open"
      ws.send "Hello Client, you connected to: #{Socket.gethostname}. websocket server path: #{handshake.path}"


    timer = EventMachine::PeriodicTimer.new(0.5) do

      value =  (rand(100..6000) / 1000.0 )
      message = "time: #{Time.now} value: #{value.to_s}"

      ws.send message
      puts message

    end
    }

    ws.onclose { puts "Connection closed" }

    #ws.onmessage { |msg|
    #  puts "Received message: #{msg}"
    #  ws.send "Pong: #{msg}"
    #}
  end
}

【讨论】:

    【解决方案2】:

    我的逻辑是在尽可能短的时间内运行事件机器,并为您需要的随机值添加延迟。例如

    'ws.onopen { |handshake|
      puts "WebSocket connection open"
      ws.send "Hello Client, you connected to: #{Socket.gethostname}. websocket server path: #{handshake.path}"
    
    
    timer = EventMachine::PeriodicTimer.new(0.0) do #the delay is kept to minimum here
    
      value =  (rand(100..6000) / 1000.0 )
      message = "time: #{Time.now} value: #{value.to_s}"
    
      ws.send message
      puts message
     delay(2) #2 seconds delay or the dynamic delay you want
    end
    }`
    

    上下文:自己尝试过

    【讨论】:

    • 为您的回答提供上下文会很有帮助
    猜你喜欢
    • 1970-01-01
    • 2017-09-15
    • 2022-07-15
    • 2018-10-25
    • 2019-11-12
    • 2014-02-04
    • 2014-10-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多