Send message form outside EM block
hey @imanel
I have been trying to send a message to the client from outside the EM block without success. I have the implementation in a Biometric module. I want from my controller to be able to set a message which will be sent to the client Biometric.set_message. When the message @@ms is not nil, send then message ws.send @@ms.
How can I be able to implement it?
require 'websocket-eventmachine-server'
require 'json'
module Biometric
@@ms = nil
def self.start
EM.run do
WebSocket::EventMachine::Server.start(host: '0.0.0.0', port: 7788) do |ws|
ws.onopen do
puts 'Client connected'
end
ws.onmessage do |msg, type|
puts "Received message: #{msg} #{type}"
end
ws.onclose do
puts 'client disconnected'
end
ws.send @@ms.to_json unless @@ms.nil?
end
end
end
def self.set_message(msg)
@@ms = msg
end
end
Biometric.start
Biometric.set_message('hello there')
The issue here is that EM.run is starting EventMachine, an infinite loop, so it will never exit it (unless server shutdown). So after Biometric.start next line is not executed unless you press "ctrl+c", at which point server will stop no longer be active.
The question is when would you like to send message to client? On connect? Or basing on some external trigger? If during connection then you want to use ws.send inside onopen, otherwise the logic that will trigger ws.send still need to be handled within EM.run block.
If you will describe exact use case you would like to achieve then I will gladly help.
@imanel Thanks for the response. I want to send a message based on an external trigger, For example, when a user clicks a button on the user interface I initiate an action from my controller which goes to the EM block and sends data.
If that's the case then usually you should have WS client build into your web server, and send messages from it. Overall WS server should be as lightweight as possible, and only relay messages (or apply small filtering logic about to whom particular message should be delivered). Combining Web and WS server will often lead to much less stable applications, especially during deploys (WS server should rarely be restarted or re-deployed).
Hey, @imanel I deployed the implementation, and was running well, I noticed after adding new changes they don't pick. I guess there might be a problem with restarting the Eventmachine to use the latest changes.
I using passanger server with nginx with Capistrano for deployment.
Capistrano will restart Rails server, however not EM one, so you need to script it by yourself. Unfortunately it's been a while since the last time I was using Capistrano, so I won't be able to help you with writing the script.
Thank you, I will research more.