Search code examples
phoenix-frameworkphoenix-channels

When to use {:noreply, socket} vs {:reply, :ok, socket} in a Phoenix Channel?


I'm building a Javascript client app that has live communication with a Phoenix server, and wants to know if a message pushed to the server has been received. It looks like Phoenix's socket.js wants me to use something like:

channel.push("mymessage", {data: 123})
  .receive("ok", function(){ console.log("Message pushed successfully"); });

However, I can't get this event handler to fire unless I change my return value on the Phoenix app to be {:reply, :ok, socket}, like so:

  def handle_in("mymessage", %{"data" => data} = payload, socket) do
    {:reply, :ok, socket}
    # not {:noreply, socket}
  end

I guess it makes sense that {:noreply, socket} doesn't actually send a message in response to the client, but in what case would you want to send a message to the server and not have it let you know that it worked? Or am I misunderstanding something? I feel like with normal HTTP requests, you always check if the request was successful from the client.


Solution

  • You're right: {:reply, :ok, socket} will send a reply message with "ok", and {:noreply, socket} won't send anything in response. You should use the former if you want to ensure that the message was sent, but often that's impractical or unnecessary (think of broadcasting a chat message to thousands of connected users--it's impractical to track "ack" messages for all of them).

    I feel like with normal HTTP requests, you always check if the request was successful from the client.

    WebSockets exist for situations that normal HTTP requests don't work well, and one-way communication is one of those cases.