使用ActionCable检测上一个窗口/选项卡关闭

时间:2017-06-01 12:28:17

标签: ruby-on-rails actioncable

我正试图找到一种方法来检测用户的最后一个窗口或标签是否正在关闭,这样我就可以做一些清理工作;但我似乎无法找到一种方法来检测它实际上是用户的最后一个连接。我有一个跟踪我的频道连接的模型,如果他们有其他活动标签打开连接,我不想删除用户的连接记录。

所以我需要检查每个断开连接以查看它们是否是具有相同标识符的其他活动连接。

我尝试在disconnect方法中设置RemoteConnections的检查。但是当它被调用时,看起来关闭的连接仍然在RemoteConnections下返回。

module ApplicationCable
  class Connection < ActionCable::Connection::Base
    identified_by :current_user

    def connect
      self.current_user = find_verified_user
      logger.add_tags 'ActionCable', current_user.username
      logger.debug self.current_user.username + " now connected."
    end

    def disconnect
      self.close()
      logger.debug ActionCable.server.remote_connections.where(current_user: current_user)
      logger.debug ActionCable.server.remote_connections.where(current_user: current_user).identifiers
      logger.debug ActionCable.server.remote_connections.where(current_user: current_user).identifiers.inspect()
    end
end

即使使用该标识符的最后一个连接正在关闭,此设置也会返回以下内容:

[ActionCable] [swachtma@gmail.com] UserChannel stopped streaming from user:Z2lkOi8vYWxseWNoYXQvVXNlci80Nw
[ActionCable] [swachtma@gmail.com] #<ActionCable::RemoteConnections::RemoteConnection:0x00000007062690>
[ActionCable] [swachtma@gmail.com] #<Set:0x00000007791b78>
[ActionCable] [swachtma@gmail.com] #<Set: {:current_user}>

到目前为止,我一直在设置一个模型来跟踪每个频道打开和关闭时的连接。但它增加了很多开销,管理起来很麻烦。

有人可以建议一种方法来管理它吗?我一直在搜索ActionCable的API文档并且空洞。

1 个答案:

答案 0 :(得分:1)

我找到了一个可能对每个人都不适用的解决方案,但由于这些是几个SO问题,没有回答,我想我会发布我最终的内容,也许它会帮助其他人。< / p>

我放弃了查询有线服务器以计算活动连接的想法。如果目前这是可能的,我显然不够明智,无法找到答案。

我还尝试使用Active Record计算活动连接,存储GIDS以识别它们,并在最后一个连接关闭时进行清理。它起作用......但我不是粉丝,因为它增加了大量的额外查询,跟踪订阅的新模型,以及围绕清理工作时间的很多敏感性。可能,但很难看。

相反,我采用了“主”和“奴”的概念,连接,以及一个额外的UserChannel(由我的用户身份验证驱动)。基本上,启动第一个订阅的连接成为“主”连接(对于聊天室,在我的情况下)。当主加入时,我通过UserChannel向通知为同一用户的所有其他活动窗口/选项卡广播通知。接收此广播的用户通过在单独但配对的从属通道上建立连接来跟随主连接。 “主”连接也建立了自己的匹配“从”连接。

因此,对于每个聊天室,我都维护着2个频道:房间_#奴隶,房间 #_ master

聊天室活动的所有广播都发生在“从属”频道上(因为它可供用户的所有会话使用,而只有一个窗口/标签订阅主节目)。新消息,用户出口,入口等在这里播出。

“主”通道仅用于处理设置和拆卸。当用户加入时,主通道的“订阅”方法通过“从”通道向其他用户广播该用户的条目。

当主连接关闭时,它的“unsubscribed”方法广播出口,处理活动记录清理,并向所有从属连接广播消息,以使该用户进入暂停状态。然后,从站可以选择(通过用户操作)成为新的主连接,在这种情况下,连接将恢复。

这是我能找到的最佳平衡;就ActiveRecord而言,只有一个窗口/选项卡计算连接。如果该窗口关闭,则用户已“离开”。但是,从通道允许我在所有用户的浏览器窗口/标签上保持一个共同状态,因为它们仍然可以看到所有发送的广播。如果用户意外关闭了“主”连接,则他们可以轻松地重新加入。