skyqrose

skyqrose

Feature request: Reply to socket connect

Proposal:
I wish the socket connect/3 callback could allow returning a reply to the frontend, which would then be visible in phoenix.js as an argument to the callback given to socket.onOpen.

I think this would be straightforward to add to successful connections, which is my main request.

It would be harder but even more useful if a reason could be passed to the frontend for rejecting a connection.

Use Case:
I want to reject a socket connection and tell the frontend why.

Currently, phoenix can use the error_handler config (docs) to say why a connection was rejected, and this reaches the browser (it’s visible in dev tools) but it’s not visible to phoenix.js. The arguments to the onError and onClose callbacks are identical no matter what error is sent, and they’re even identical to the error that phoenix.js receives when there’s a network error.

My JS app needs to tell different connection errors apart in order to handle them differently. On a network error it should try again (the deafult). On an authn error it should not try again and should redirect to the login page. If the frontend app version is outdated it should refresh. Other applications may have app-specific handlers for other errors.

Workaround:
Because I can’t send a useful error message, I allow the socket to connect, even if there are authentication problems, and then store the auth details in socket.assigns, and check authentication on every channel join.

Then, I wish I could reply to the socket connect to tell the client about any authentication problems so that the frontend could handle them. But there’s no way to reply with a payload to socket connect/3. So instead, I need a workaround within my workaround:

After successfully connecting to a socket, the client immediately joins a channel within that socket (I named it “metadata”), and that channel replies to the join with a payload that describes any authentication or other problems that the client should handle in a custom way.

If a socket fails to connect, the client can know that it’s definitely because of network problems, not auth problems, and it can retry in the default way.

Including a reply with a rejected socket connection:
This would most directly address my use case, but might be difficult. There’s probably a reason that browsers don’t expose websocket connection failures to JS. It might require backwards incompatible changes to how error handlers for connect/3 are done. I’d like this idea to be at least considered, but it’s okay with me if there’s reasons not to do it.

I saw a number of other threads on this forum and others about this issue, so I think it’s something that many people are running into.

Including a reply with an accepted socket connection:
This would make my workaround much simpler. I wouldn’t need the separate “metadata” channel, and it’d save a network round trip during the connection process. I could send any authentication problems or other metadata directly via the socket reply, and the client could handle it immediately after connecting.

I expect it’d be relatively easy to implement. The interface would be an extra {:ok, reply, socket} case to the return type of connect/3, and an argument passed to the onOpen callback, both of which are backwards-compatible changes.

I haven’t seen others asking for this idea like I’ve seen others wanting to reply with a rejection reason, but I think it would still be generally useful. Not just for authentication issues like me, but I’m sure there are plenty of application-specific use cases for something like this, like replying with user metadata that the client didn’t know before joining.

This feature is my main suggestion and reason for making this post.

The only risk I can see with something like this is that being able to send data on a socket outside of a channel (even if it’s just a one-time reply) could make learning the distinction between sockets and channels more confusing. I can imagine people asking when to use socket replies and when to use channel replies. But this is minor.

Summary:
It’d be nice if it was possible to reply to a socket connection (maybe rejection reasons, but probably just accepted connections) with a payload.

Most Liked

entone

entone

You should be able to utilize the HTTP response status for handling different connection errors. We currently use this for handling rate limiting vs auth errors.

Where Next?

Popular in Proposals: Ideas Top

marcandre
I notice that most events have bindings (e.g. phx-keyup) but not the input event. The input event is the preferred way to interact with ...
New
nocksock
LiveView has spoiled me and now I would LOVE to be able to write controllers like this: defmodule DeadViewWeb.ItemController do use De...
New
sevensidedmarble
All the pieces are there to execute arbitrary JS commands from the server. You can put them on a data property and call them from the cli...
New
cgraham
Please change passwordless login from a link to a 6-8 digit code a user can enter. Gen Auth in the latest RC 1.8 of Phoenix defaults ...
New
superchris
Hello! After seeing a couple of posts from Chris and Jose about supporting web components in LiveView, I thought it would be great to ini...
New
kccarter
This is likely a feature request unless we’re overlooking something, but it would be a nice improvement to the developer experience if th...
New
mxgrn
As one edits a Phoenix LiveView form in a modal, it’s very easy to accidentally press ‘Esc’ and lose all the edits. Similar to data-conf...
New
Aduril
Hello there, Whenever I setup a new project, there is a small function I always add: reply/1. What does it do? In a LiveView mount, han...
New
dogweather
Hi Phoenix community! First off, huge thanks for an amazing framework - Phoenix has been a joy to work with. I have a small UX suggestio...
New
sevensidedmarble
I have a very simple suggestion: the generated config/dev.exs file should read from PORT at compile time to set the endpoints port. If ...
New

Other popular topics Top

JeremM34
Hello, how can I check the Phoenix version ? Thanks !
New
jononomo
I am trying to figure out how Mix knows whether the environment is test, dev, or prod – where is this set? Thanks.
New
stefanchrobot
What’s the safe way to decode a JSON string into a struct? I want to avoid calling String.to_atom. Jason.decode can give me a map with st...
New
fayddelight
I tried installing elixir 1.11.2 erlang 23.3.4 via asdf in my zsh shell. Enabled the versions locally and globally. When I list them ...
New
boundedvariable
I am going through the kafka architecture. All the features what the kafka is providing are already in Erlang. I would like hear your opi...
New
romenigld
I am trying to run a deploy with docker and I successfully runned with this command: docker build -t romenigld/blog-prod . but when I t...
New
shijith.k
I am trying to start a new phoenix project with elixir 1.9, but mix phx.new does not work. It says that ** (Mix) The task "phx.new" could...
New
svb
Hi! Currently I want to submit a form by pressing the Enter key. However, since my input field is of type “textarea” this is just adds a...
New
sergio
Kind of like when jquery came out, it was super necessary. Existing drag and drop libraries have a bunch of baggage to support old browse...
New
lanycrost
Hi everyone! I need implement if…else if…else condition from my elixir code, and anymore of this control flow structures not work proper...
New

Latest on Elixir Forum

We're in Beta

About us Mission Statement