vincent15000's avatar

Laravel / VueJS application open in a browser set in the background

Hello,

I have a real time application using a websocket and the authentication is done via a token generated by Sanctum API token. The connection to the websocket is also protected by the Sanctum API token.

If the websocket connection is lost, no problem, it displays a message on the screen to inform the user and if needed suggest him / her to refresh the screen or reconnect. This is done by listening to the websocket events (for example state_change, connecting, connected, ...).

But when the browser is set to the background (not closed, but just by using another software instead), when I put the browser back to the foreground some hours later, I'm not connected to the application anymore, but no message is show on the screen to inform the user.

Soketi has an automatic ping / pong to check the websocket health, so my first ideas are :

  • either the ping / pong is not done anymore

  • or the token is invalid

For the moment I have only one question : if the websocket connection is healthy and after some hours the authentication token has expired, does the websocket connection remain active ?

Do you have any other idea why I have this problem with a browser in the background ?

Thanks a lot for your help.

V

0 likes
1 reply
LaryAI's avatar
Level 58

To address the issue you're experiencing with your Laravel/VueJS application when the browser is set to the background, there are a few considerations and potential solutions you can explore:

  1. Token Expiry Handling:

    • If the authentication token expires while the browser is in the background, the websocket connection might still appear active but won't be able to authenticate any new requests. You need to handle token refresh logic.
  2. WebSocket Reconnection Logic:

    • Implement a reconnection strategy for your websocket. This can help in re-establishing the connection when the browser comes back to the foreground.
  3. Visibility API:

    • Use the Page Visibility API to detect when the browser tab becomes visible again and then check the websocket connection status.

Here's a potential solution combining these ideas:

Step 1: Token Refresh Logic

Ensure you have a mechanism to refresh the token before it expires. This can be done using an Axios interceptor in VueJS.

import axios from 'axios';

// Add a request interceptor
axios.interceptors.request.use(async (config) => {
  // Check if the token is about to expire
  const tokenExpiry = localStorage.getItem('tokenExpiry');
  const now = new Date().getTime();

  if (tokenExpiry && now > tokenExpiry - 60000) { // 1 minute before expiry
    // Refresh the token
    const response = await axios.post('/api/token/refresh');
    const newToken = response.data.token;
    const newExpiry = response.data.expiry;

    // Update token and expiry in local storage
    localStorage.setItem('token', newToken);
    localStorage.setItem('tokenExpiry', newExpiry);

    // Update the request with the new token
    config.headers['Authorization'] = `Bearer ${newToken}`;
  }

  return config;
}, (error) => {
  return Promise.reject(error);
});

Step 2: WebSocket Reconnection Logic

Implement a reconnection strategy for your websocket.

let socket;

function connectWebSocket() {
  socket = new WebSocket('wss://your-websocket-url');

  socket.onopen = () => {
    console.log('WebSocket connected');
  };

  socket.onclose = () => {
    console.log('WebSocket disconnected, attempting to reconnect...');
    setTimeout(connectWebSocket, 5000); // Reconnect after 5 seconds
  };

  socket.onerror = (error) => {
    console.error('WebSocket error:', error);
  };

  socket.onmessage = (event) => {
    console.log('WebSocket message:', event.data);
  };
}

connectWebSocket();

Step 3: Page Visibility API

Use the Page Visibility API to detect when the browser tab becomes visible again.

document.addEventListener('visibilitychange', () => {
  if (document.visibilityState === 'visible') {
    // Check if the websocket is still connected
    if (socket.readyState !== WebSocket.OPEN) {
      console.log('WebSocket is not open, reconnecting...');
      connectWebSocket();
    }
  }
});

Step 4: Display Message to User

Ensure you display a message to the user if the websocket connection is lost.

socket.onclose = () => {
  console.log('WebSocket disconnected, attempting to reconnect...');
  alert('Connection lost. Attempting to reconnect...');
  setTimeout(connectWebSocket, 5000); // Reconnect after 5 seconds
};

By implementing these steps, you should be able to handle token expiry, websocket reconnection, and notify the user when the connection is lost. This should help mitigate the issues you're experiencing when the browser is set to the background.

Please or to participate in this conversation.