Giorgio Robino
Giorgio Robino

Reputation: 2273

event machine websocket server: how to push periodic messages to client?

I would like to use ruby language gem em-websocket: https://github.com/igrigorik/em-websocket to run a websocket server above eventmachine.

I run susccessfully the echo server demo:

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
}

now I'd like to develop a demo where the server could push every n msecs (random value) some data through a websocket message to a connected client... virtually something like:

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

I'm aware I can NOT use sleep() system call inside the EM loop, but I cant' figure out how to insert a periodic event in the EM::WebSocket loop; maybe with EventMachine::PeriodicTimer ? how ?

Someone can help me with a code example chunck ? thanks! giorgio

Upvotes: 1

Views: 1568

Answers (2)

WingCode
WingCode

Reputation: 23

My logic would be to run the event machine for the minimum duration possible and add a delay for the random value you require. For example

'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
}`

Context: Self tried

Upvotes: -1

Giorgio Robino
Giorgio Robino

Reputation: 2273

I found a solution myself: In the code below, server push a websocket message to client every 500 msec. ( PeriodicTimer.new(0.5) ).

The problem I have now, is how to dinamically reset the timer to send a message every N msecs where N is a random value... Any idea ?

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
}

Upvotes: 3

Related Questions