phollyer

phollyer

There are two different scenario’s I’m trying to handle with the Phoenix JS Websocket client - both produce the same result but I need to handle them both differently.

1. The application is not accessible/responding.
2. Denying a user connection due to failing authentication.

I am authenticating and then denying connection as per the comments for UserSocket.connect/2:

# To deny connection, return `:error`.

1 socket.onError() fires and the socket tries to reconnect again. This is the expected behaviour and is what would be wanted in this scenario.

2 socket.onError() fires and the socket tries to reconnect again. This is not the behaviour I would expect or want. If connection is denied due to failing authentication, then I would not want the socket to keep trying to connect.

If I call socket.disconnect() when the connection is denied, then this stops the repeated attempts to connect again (which seems strange as the socket hasn’t connected yet). This is fine for 2, but not what I would want for 1.


So how do you differentiate between to the two scenarios? Both scenarios fire the same callback function but with no useful data to know which scenario is being responded to?

Or am I looking at this all wrong?

Thanks

Showing Posts 1 to 9

LostKobrakai

LostKobrakai

Afaik phoenix channels just build on top of the browsers websocket functionality and based on the event given to the onClose callbacks it seems the websocket connection doesn’t hold data to keep both cases apart. So there might not really be much phoenix can do about it.

outlog

outlog

for technical/specification reasons - you cant know if the onError is called due to wrong auth.. what I do is make an ajax call to “auth_check” and if that fails with 401 - I disconnect, clear the bad token, and navigate to the appropriate place (most likely login screen..) - in any other case I let the reconnect run (as it’s most likely lack of connection or server down that is the issue then)

phollyer

phollyer OP

Thanks, I’m using ajax as you suggested to determine the reason for onError, this at least allows me to report the correct state back to the user.

My only remaining problem is that I can’t seem to stop the socket from trying to reconnect all the time when auth fails. socket.disconnect() has no effect - presumably because the socket hasn’t opened as a result of the failed auth in UserSocket.connect/2.

Is it even possible to stop the socket from trying to reconnect all the time?

NobbZ

NobbZ

What if you accept the connection anyway and join a personal management channel, where then you send back a response that tells the client it were unauthorized and not allowed to use the connection, then on the client you can safely shut down the connection.

The problem with this though is, if you have a misbehaving client, the connection will be lingering open… But is this worse than a client that steadily tries to reconnect even if it is not authorized?

phollyer

phollyer OP

Yes, thanks, that’s what I’ve been doing - allowing the socket to connect then handling the auth on the channel.

However, reading the comments in UserSocket, I wanted to try setting it up the ‘phoenix way’ handling the auth in connect/2, but if I can’t stop the socket from trying to reconnect, I’ll probably go back to handling the auth on the channel. I guess I’d rather have the odd connection lingering open than the client trying to reconnect all the time.

Thanks for the input.

amnu3387

amnu3387

@phollyer have you tried to set the socket to null once you’re sure you can’t reconnect? And then setting it up again once you login (or wtv)?

phollyer

phollyer OP

Hadn’t, but have now, and the socket still tries to reconnect.

I’ve done some digging around in the socket object though and the following stops the socket from trying to reconnect:

socket.reconnectTimer = {scheduleTimeout: function() { return null }}
peerreynders

peerreynders

import {Socket} from "phoenix"

let socket = new Socket("/socket", {params: {token: window.userToken}})

let cancelTimeout = true
function openListener(_event) {
  // once successfully opened
  // try to reconnect
  cancelTimeout = false
}
function closeListener(_event) {
  if(cancelTimeout) {
    // don't retry as it is likely a failure to authenticate
    socket.reconnectTimer.reset() // cancel automatic reconnect
  }
}
socket.onOpen(openListener) 
socket.onClose(closeListener) 
socket.connect()

Unfortunately the WebSocket doesn’t have access to the 403 status code and the CloseEvent code always seems to be 1006 “Abnormal Closure”.

phollyer

phollyer OP

Thanks, makes perfect sense. Hadn’t thought of it that way, such a simple solution. :+1:

— All posts loaded —

Where Next? Top

Trending in Questions Top

RSP87
I’m working on a project that simulates the bumbl example in the programming phoenix book. It acts almost like an email client. We have a...
New
nseaSeb
Hello, I know there is an approach for handling lists that allows for optimized traversal, but I can’t recall the specific method (somet...
New
brecabral
Documentation While reading the Scoped Routes section, I noticed that the documentation currently refers to a problem without explainin...
New
RemyXRenard
I’m seeing that a list inside a Kino.DataTable will be interpreted as a charlist, even if the Kino.configure() is set to charlists: :as_l...
New
velrest
So my question is quite simple and i have found no conclusive answer on forum, google or AI. Should we use :erlang.float for Integer to ...
New
samoloth
Hi, I’ve just set up an application with ash_authentication. There is only magic link strategy for now, so there is no confirmation add o...
New
FlyingNoodle
If a change or preparation module uses Ash.Changeset.get_argument/2 or Ash.Query.get_argument/2 (or any of the other get_argument functio...
New

Other Trending Topics Top

JesseHerrick
Hey, I’m Jesse and I’m the main contributor behind Dexter, a full-featured, lightning-fast Elixir LSP optimized for large codebases. It s...
New
mudasobwa
I am happy to introduce the very α version of the new programming language compiled to BEAM. Welcome Cure. It has literally three kille...
New
marciok
Hi there! We created Gust: A task orchestrator inspired by Airflow. For those who have never heard about Aiflow, it’s a Python-based wor...
New
mhanberg
Hi everyone! The first release candidate for the Expert language server project is now available! We’ve published a press release detai...
New
jimsynz
Beam Bots (or just BB for short) is a framework for building fault-tolerant robotics applications in Elixir using familiar OTP patterns. ...
New
Dmk
Xamal is a deployment tool for Elixir apps that deploys native releases to bare metal servers over SSH. It’s a port of GitHub - basecamp/...
New

We're in Beta

About us Mission Statement

Options

Thread Display Mode




Thread Preview

Skip Thread Previews