Help with multi-subscription channels

how do i subscribe to multiple channels? and handle their events on a per channel basis use case is i have multiple users/agents sub to many channels where a lead topic is broadcast agents need to be able to accept the lead and have it dissappear from the other users screens would i just write a function that pushes some data to a diff topic to remove the “lead” im using drab to push/pull all this via the controller/commander so i can have priortization of the queue eventually, can i just do something like how is this on terms of performance code correctness? is this a good idea?

city.js
import socket from "./socket"


$(function () {
   var citys =  ["phoenix","tucson"]
    forEach(function(citys, val) {
    
        var topic = "city:" + val
        // Join the topic
        var channel = socket.channel(topic, {})

        channel.join()
            .receive("ok", data => {
                console.log("Joined topic", topic)
            })
            .receive("error", resp => {
                console.log("Unable to join topic", topic)
            })

        channel.on("new", resp => {
            console.log("a new lead has been recieved from client:", resp);
        })

        channel.on("booked", resp => {
            console.log("a new lead has been booked from agent:", resp);
        })
    });
    
});

city channel 
defmodule Broker.CityChannel do
  use Broker.Web, :channel

  def join("city:lobby", payload, socket) do
    if authorized?(payload) do
      {:ok, socket}
    else
      #{:error, %{reason: "unauthorized"}}
       {:ok, socket}
    end
  end

  def join("room:" <> _private_room_id, _params, _socket) do
      {:error, %{reason: "unauthorized"}}
    end

  # Channels can be used in a request/response fashion
  # by sending replies to requests from the client
  def handle_in("ping", payload, socket) do
    {:reply, {:ok, payload}, socket}
  end

# send the new lead to all agents in the city
 def broadcast_lead(lead) do

    payload = %{
    title: "test new lead"
    }
    Broker.Endpoint.broadcast("lead:#{lead.uuid}", "new", payload)
  end

  # It is also common to receive messages from the client and
  # broadcast to everyone in the current topic (city:lobby).
  def handle_in("shout", payload, socket) do
    broadcast socket, "shout", payload
    {:noreply, socket}
  end
 def handle_in("lead", %{"body" => body}, socket) do
    broadcast! socket, "lead", %{body: body}
    {:noreply, socket}
  end
  # Add authorization logic here as required.
  defp authorized?(_payload) do
    true
  end
end

i do something like this via the controller

Broker.CityChannel.broadcast_lead(lead_data)

That looks entirely valid yeah, except you not handling a topic starting with "city:". :slight_smile:

Hi, let me revive this old question as I had a similar one.

On the client side, I’ve subscribed to channel_1 “room:lobby” and also to channel_2 “room:*”. I was hopping when messages are broadcasted in the backend for “room:lobby”, I would also get them in channel_2 but never happens.

I believe it’s a similar use-case to the original question and I see this is as quite a useful one where a client could subscribe a couple of city’s temperature and a “master” client could subscribe to all (with the “*” character).

Are there general recommendation (or tutorial or recipe) on such use-case?

@2trc same question here, how have you eventually dealt with that? Any advice would be welcome :slight_smile:

I do not believe that you can subscribe to a room:* channel and receive all messages sent to any channel whose name starts with room:.

I guess you should create a channel room:all and broadcast to it whenever some other room:<any> channel receives a message.

1 Like