Programming Phoenix LiveView: Broadcast Survey Results (page 237)

What is the difference between using PentoWeb.Endpoing.broadcast/3 and Phoenix.PubSub.broadcast/3. Also the same applies for subscribe/2
Before I read the book, I used to configure messaging system using Phoenix.PubSub.* and it was working fine actually. For example I create function in the context (boundary) call it subscribe and one call it broadcast like so:

defmodule Pento.Survey do

  @topic inspect(__MODULE__)

  def subscribe do
    Phoenix.PubSub.subscribe(Pento.PubSub, @topic)
  end
  
  def broadcast({:ok, rating}, event) do
    Phoenix.PubSub.broadcast!(
      Pento.PubSub,
      @topic,
      {event, rating}
    )

    {:ok, rating}
  end
# ... rest of code
end