我正在编写rails app,我希望用户在将新邮件保存到数据库后立即收到通知。对于websocket我使用em-websocket gem。连接后,我将客户端ID和套接字实例存储在数组中。
问题:如何从控制器\模型操作(例如before_save)将数据推送到客户端?能用em-websocket吗?
chat.rb
EVENTCHAT_CONFIG = YAML.load_file("#{Rails.root}/config/eventchat.yml")[Rails.env].symbolize_keys
#escape html/xss
include ERB::Util
Thread.abort_on_exception = true
Thread.new {
EventMachine.run {
@sockets = Array.new
EventMachine::WebSocket.start(EVENTCHAT_CONFIG) do |ws|
ws.onopen do
end
ws.onclose do
index = @sockets.index {|i| i[:socket] == ws}
client = @sockets.delete_at index
@sockets.each {|s| s[:socket].send h("#{client[:id]} has disconnected!")}
end
ws.onmessage do |msg|
client = JSON.parse(msg).symbolize_keys
case client[:action]
when 'connect'
@sockets.push({:id=>client[:id], :socket=>ws})
@sockets.each {|s| s[:socket].send h("#{client[:id]} has connected!")}
when 'say'
@sockets.each {|s| s[:socket].send h("#{client[:id]} says : #{client[:data]}")}
end
end
end
}
}
答案 0 :(得分:0)
部署时 - 您可能遇到与在每个rails工作者中都有一个单独的EM反应器相关的问题(例如,有些错误导致某些用户无法绑定到套接字或未接收到所有消息的所有用户)
与websocket reactor相关的Rails控制器只是另一种类型的客户端,最简单的方法是打开具有特殊客户端ID的连接,推送一些数据并在之后关闭它。更有效的方法 - 保持每个铁路工人的开放连接
如果使用基于EM的单进程服务器(例如 - thin
),您可以使用EM::Queue
将消息传递给进程中的websocket worker,甚至可以直接从控制器写入websocket