我正在使用ActionCable来提供易于实现的浏览器通知。当用户在浏览器中打开多个选项卡并且我需要将数据仅发送到一个选项卡,即只发送到用户房间中的一个WebSocket时,问题就出现了。如何才能做到这一点?
使用pub / sub方法无法直接隔离单个pub / sub客户端,因为整个想法是发布者不了解订阅者。
但是,有两种常见的方法可以解决这个问题:
user-ID-TIMESTAMP
保存在数据库中并将其用作目标连接)。祝好运!
每次建立新连接时,我们都会创建一个新房间。因此,例如当用户建立新连接时,我们可以将房间名称作为用户:user_id:some_unique_random_string,它可以等于用户:user_id:123j123b1h2b1j23bh12b3,当同一个用户通过打开另一个选项卡建立另一个连接时,我们也会执行同样创建一个单独的房间。现在,ActionCable提供的一件事是我们可以找到所有房间名称后跟任何前缀。
让用户已经建立了三个连接,他们的房间是用户:128:123n1jh123ko9876,用户:128:asdas23412cs1234,用户:128:asni9202h5i3jens然后我们也可以使用ActionCable获取这些房间名称。
user_id = 128
pubsub = ActionCable.server.pubsub
channel_with_prefix = pubsub.send(:channel_with_prefix, RoomChannel.channel_name)
channels = pubsub.send(:redis_connection).pubsub('channels', "#{channel_with_prefix}:users:#{user_id}:*")
现在,频道是一个由房间名称组成的数组。
所以puts channels
["chatapp_production:users:128:123n1jh123ko9876", "chatapp_production:users:128:asdas23412cs1234", "users:128:asni9202h5i3jens"]
这就是我们如何在不使用任何外部数据库和API调用的情况下找到与单个用户相关的所有房间的方法。