我目前正在使用Rails为反应和反应原生应用程序做准备。令牌用于身份验证。
我的应用程序中有两个功能需要WebSockets:
我看到了两种实现WebSockets的方法:
两个独立的频道
我在客户端打开应用程序时订阅的第一个频道:NotificationChannel
,如果需要,我会广播......
我打开聊天时订阅的第二个频道:ChatChannel
,代码如下:
class ChatChannel < ApplicationCable::Channel
def subscribed
authorize_chat_room_id(params[:chat_room_id]) #
stream_from "chat_channel_#{params[:chat_room_id]}"
end
# here methods for receiving data from client
# maybe some other methods for tracking if sb is typing and so on
# private authorize_chat_room_id method
end
在这种情况下,用户最多订阅2个频道,授权仅在订阅聊天时执行一次。
在这种方法中,我只授权用户一次,当他订阅频道时,我不知道如何打开2个频道而不是1,影响服务器的性能。
一个频道
单个频道将被称为:PersonalChannel
,并将处理所有信息流,代码看起来像这样:
def subscribed
stream_from "personal_channel_#{current_user.id}"
end
def send_message(data)
if authorize_chat_room_id(data['chat_room_id'])
#create message
end
end
def start_typing(data)
if authorize_chat_room_id(data['chat_room_id'])
# some broadcast
end
end
当我进行广播时,我会发送有效负载作为示例类型(例如&#39; MESSAGE_SEND&#39;),并且基于此,如果聊天将打开,则客户端将打印该消息。 / p>
这种方法的优点是,在发送消息时,我只能向一个用户广播,而我不会从频道收到消息。但在这种情况下,我必须每次都授权执行一个动作。
我的问题是哪种解决方案在性能方面会更好,什么是普遍接受的方法(使频道非常通用或使每个频道处理单一任务)?
答案 0 :(得分:1)
在这个问题上,我建议您考虑优先考虑代码维护问题而不是性能。
channels
的概念允许我们将发布商与消费者分离。这简化了大量代码并有助于分离关注点。
例如,在聊天室中发帖的用户不需要知道(也不管理)有多少人订阅该聊天室,也不知道他们是谁。这些问题现在由pub / sub系统而不是用户处理。
这种关注点的分离使得添加或删除聊天成员变得更加容易(您不需要更新每个用户,只需要更新发布/订阅系统)。
这种分离还可以防止存储多个数据副本(发布/订阅系统只保存有效副本)。
从长远来看,通过将所有数据整合到一个PersonalChannel
中,您将重新引入发布者和消费者之间的耦合 - 这将增加复杂性并使维护模式随着时间的推移变得困难。
在聊天室示例中,每个用户都需要获取所有会议室成员的副本,并将每封消息发送给所有用户。这增加了(成员列表的)副本数量,并引入了同步问题。
这种方法的优点是,在发送消息时,我只能向一个用户广播,而我不会从频道收到消息。但在这种情况下,我必须每次都授权执行一个动作。
这个优势实际上是你可以通过订阅每个用户订阅个人频道以及其他频道使用第一种方法轻松实现的,订阅三个频道而不是两个频道。