PhoenixFrameworkを使用してクライアントにリアルタイムメッセージを送信する必要があるWebソケットサーバーを開発しています。
私のWebソケットサーバーの基本的な考え方は、クライアントはある種の情報をサブスクライブしてそれだけを受信することを期待でき、他のクライアントもサブスクライブしない限りそれを受信しないということです。同じ情報がすべての人にブロードキャストされます(そして)クライアントはリアルタイムでサブスクライブしました。
また、これらの情報はカテゴリとサブカテゴリに分けられ、4つのレベルのカテゴリに分類されます。
したがって、たとえば、のは、私はカテゴリ情報の2種類を持っているとしましょうCatA
、とCatB
、各カテゴリにはサブカテゴリーを持つことができ、そうCatA
することができCatA.SubCatA
、およびCatA.SubCatB
サブカテゴリー、各サブカテゴリーも、他のサブカテゴリなどを持つことができます。
これらの情報は、ルートカテゴリごとに1つずつサービスによって生成されるため(サブカテゴリのすべての情報も処理します)、とがCatAService
ありCatBService
ます。これらのサービスは、サーバーの起動時に実行する必要があり、常に新しい情報を生成し、それをサブスクライブしているすべての人にブロードキャストします。
現在、これらの情報をサブスクライブしようとするクライアントがいます。今のところ、私の解決策は、各情報タイプのチャネルを使用できるようにすることです。これにより、クライアントはチャネルに参加して、チャネルのタイプの情報を受信できます。
そのために私はjsコードにそのようなものを持っています:
let channel = socket.channel("CatA:SubCatA:SubSubCatA", {})
channel.join()
channel.on("new_info", (payload) => { ... }
この場合、私が興味を持ってすべてのクライアントというチャンネルだろうSubSubCatA
からSubCatA
からは、CatA
参加することができますし、ためのサービスCatA
それはように生成し、そのすべてのサブカテゴリの情報を放送してますが。
自分の欲しいものを正確に説明できたかどうかはわかりませんが、不明な点がある場合は、説明しやすいように教えてください。また、この(非常に悪い)画像をすべての例として作成しました。通信はhttps://ibb.co/fANKPbで発生します。
また、カテゴリごとに1つのチャネルしかなく、そのカテゴリチャネルに参加したすべての人にすべてのサブカテゴリ情報をブロードキャストできることに注意してください。ただし、パフォーマンスとネットワーク帯域幅が非常に心配なので、情報を送信するのはそれを要求したクライアント。
ここでいくつかのテストを行うと、上記のjsコードに示されているようにクライアントがチャネルに参加する場合、次のことができるようです。
MyServerWeb.Endpoint.broadcast "CatA:SubCatA:SubSubCatA", "new_info", message
そして、そのクライアント(およびそのチャネルをリッスンしている他のすべてのクライアント)がそのメッセージを受信します。
したがって、私の質問は2つの部分に分かれています。1つはより一般的であり、上記で説明したことを達成するための正しい方法は何ですか。
2つ目は、文字列「CatA:SubCatA:SubSubCatA」の長さがサーバーの解析時にオーバーヘッドを生成するかどうかわからないため、すでに思いついた解決策がこれを解決するための良い方法であるかどうかです。私が知らない制限。
ありがとう!
クライアントのクラスごとに個別のチャネルを作成する必要があり、取得するIDに応じて、チャネルに参加しているクライアントについて確認した後、メッセージをブロードキャストできます。
def join("groups:" <> group_slug, _params, socket) do
%{team_id: team_id, current_user: user} = socket.assigns
case Repo.get_by(Group, slug: group_slug, team_id: team_id) do
nil ->
{:error, %{message: "group not found"}}
group ->
case GroupAuthorization.can_view?(group.id, user.id) do
true ->
messages = MessageQueries.group_latest_messages(group.id, user)
json = MessageView.render("index.json", %{messages: messages})
send self(), :after_join
{:ok, %{messages: json}, assign(socket, :group, group)}
false ->
{:error, %{message: "unauthorized"}}
end
end
終わり
これは、サブスクライブしてグループに参加しているグループのユーザーにのみメッセージを送信する例です。お役に立てれば。
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加