0

我正在编写 rails 应用程序,我希望用户在新消息保存到数据库后立即收到通知。对于 websocket,我使用的是 em-websocket gem。连接后,我将客户端 ID 和套接字实例存储在数组中。

问题:如何将数据从控制器\模型操作(例如 before_save)推送到客户端?是否可以使用 em-websocket 做到这一点?

聊天.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
  }
}
4

1 回答 1

0

部署时 - 您可能会遇到与在每个 rails worker 中拥有单独的 EM 反应器相关的问题(例如,有关某些无法绑定到套接字或并非所有用户都收到所有消息的错误)

与 websocket reactor 相关的 Rails 控制器只是另一种类型的客户端,最简单的方法是打开具有特殊客户端 ID 的连接,推送一些数据然后关闭它。更有效的方法 - 是与每个 Rails 工作人员保持开放连接

如果使用基于 EM 的单进程服务器(例如 - thin),您可以使用EM::Queue将消息传递给进程中的 websocket 工作人员,甚至可以直接从控制器写入 websocket

于 2015-12-04T10:17:35.230 回答