   `handle_out/3` callbacks must return one of:
 
       {:noreply, Socket.t} |
+      {:noreply, Socket.t, timeout | :hibernate} |
       {:stop, reason :: term, Socket.t}
 
   """

  @type socket_ref :: {transport_pid :: Pid, serializer :: module,
                       topic :: binary, ref :: binary, join_ref :: binary}

  @callback join(topic :: binary, auth_msg :: map, Socket.t) ::
              {:ok, Socket.t} |
              {:ok, map, Socket.t} |
              {:error, map}

  @callback handle_in(event :: String.t, msg :: map, Socket.t) ::
              {:noreply, Socket.t} |
              {:noreply, Socket.t, timeout | :hibernate} |
              {:reply, reply, Socket.t} |
              {:stop, reason :: term, Socket.t} |
              {:stop, reason :: term, reply, Socket.t}

  @callback handle_out(event :: String.t, msg :: map, Socket.t) ::
              {:noreply, Socket.t} |
              {:noreply, Socket.t, timeout | :hibernate} |
              {:stop, reason :: term, Socket.t}

  @callback handle_info(term, Socket.t) ::
              {:noreply, Socket.t} |
              {:stop, reason :: term, Socket.t}

  @callback code_change(old_vsn, Socket.t, extra :: term) ::
              {:ok, Socket.t} |
              {:error, reason :: term} when old_vsn: term | {:down, term}

  @callback terminate(reason :: :normal | :shutdown | {:shutdown, :left | :closed | term}, Socket.t) ::
              term


  simply relay the `%Phoenix.Socket.Broadcast{}` event and payload:

      alias Phoenix.Socket.Broadcast
      def handle_info(%Broadcast{topic: _, event: event, payload: payload}, socket) do
        push(socket, event, payload)
        {:noreply, socket}
      end

