How to update socket auth token parameter on client when connection fails and trys to reconnect?

Background: When a user loads a page, I am using PHP cURL function to authenticate a user and obtain a token from the Phoenix server, using the Phoenix API method. The token get stored in Javascript variable window.at

Problem: I am testing a scenario when a user loads the page, but the Phoenix server is down. So my cURL call cannot obtain an auth token from Phoenix upon page load. When Phoenix comes back online, the socket continues to connect over and over again without any auth token in place.

My solution attempt: When this error happens, make an AJAX call to a PHP script that continues calling the Phoenix API until Phoenix comes back online. I am able to obtain the token, store it in window.at, but the socket connection attempt is not using that updated variable, it’s using the old window.at value instead. I’ve tried resetting the socket variable to null, reinitializing a new socket variable in the ajax function, but nothing works:

window.at = '<?php echo $authtoken; ?>'; // Auth token obtained using cURL call to Phoenix API.
window.userid = '1'; 
  
let socket = new Phoenix.Socket("wss://ex.example.com/socket", {params: {user_id: window.userid, at: window.at}});

socket.connect();
socket.onError(error => {
  if(window.at == '') {
    var xhr = new XMLHttpRequest();
    xhr.open("POST", "https://www.example.com/ajax-reauth.php");
    xhr.send();
    xhr.onreadystatechange = function() {
      if (this.readyState == 4) {
	    if(this.status == 200 && this.responseText != '') {
	      result = JSON.parse(this.responseText);
		  console.log(result);
		  if(result.status == 'success') {
		    window.at = result.at; // new auth token
          }
        }
      }
    }
  }
});

let socket = new Socket(“wss://ex.example.com/socket”, {
params: () => {
return {user_id: window.userid, at: window.at};
},
});

1 Like

Edit: Ok sorry, I see what you did there. I didn’t look closely enough at your function. I assumed you meant to try reinitializing the same exact let socket = ... function in the Ajax response. Your way works by using that as the original initiation function.

After digging around for awhile before I looked at your solution again, I found another way that will work as well, which is similar to the solution above. So there are a couple of ways to solve it now:

let socket = new Phoenix.Socket("wss://ex.example.com/socket", {params: {user_id: window.userid, at: window.at}});
socket.connect();
socket.onError(error => {
  if(window.at == '') {
    var xhr = new XMLHttpRequest();
    xhr.open("POST", "https://www.example.com/ajax-reauth.php");
    xhr.send();
    xhr.onreadystatechange = function() {
      if (this.readyState == 4) {
	    if(this.status == 200 && this.responseText != '') {
	      result = JSON.parse(this.responseText);
		  console.log(result);
		  if(result.status == 'success') {
		    window.at = result.at; // new auth token
            socket.params = () => ({ user_id: window.userid, at: window.at })
          }
        }
      }
    }
  }
})

params is function