John
John

Reputation: 533

Socket.io keep the connection on client side when client refresh or open new page

Have some way to keep the same socket.io connection on client side if user open a new page or refresh the page, maybe store the socket in session or it's impossible?

Upvotes: 9

Views: 13536

Answers (3)

Sersif Samir
Sersif Samir

Reputation: 81

It's not possible (almost to not wast you time on it) if you do a F5 for example, because all of the javascript execution context objects will be reset.

But it's possible if you want to keep the socket connection alive between multiple tabs.

using the Broadcast Channel API it will help synchronize the socket connection across multiple tabs, ensuring that the connection remains active.

When a socket connection is established in one tab, it will send a message through the Broadcast Channel API to inform other tabs to establish their socket connections as well. This allows the socket connection to be shared across multiple tabs and stay alive as long as at least one tab remains open. (with the same origin).

first you need to create a service outside the react components. to keep the reference of the object.

import io from 'socket.io-client';
import {BroadcastChannel} from 'broadcast-channel';

class SocketService {
  constructor() {
    this.socket = null;
    this.broadcastChannel = null;
    this.channelName = 'socketConnectionChannel';
  }

  initializeBroadcastChannel() {
    this.broadcastChannel = new BroadcastChannel(this.channelName);

    this.broadcastChannel?.addEventListener('message', (event) => {
      if (event.data === 'connect') {
        this.connect();
      } else if (event.data === 'disconnect') {
        this.disconnect();
      }
    });
  }

  connect() {
    this.socket = io('your-socket-server-url');
    // Set up event listeners or any other necessary configuration
  }

  disconnect() {
    if (this.socket) {
      this.socket.disconnect();
      this.socket = null;
    }
  }

  sendBroadcastMessage(message) {
    if (this.broadcastChannel) {
      this.broadcastChannel?.postMessage(message);
    }
  }

  // Additional methods 'sending data'... etc.
}

export default new SocketService();

The usage within a react component:

import React, { useEffect } from 'react';
// ther service we created
import socketService from './socketService';

const MyComponent = () => {
  useEffect(() => {
    // Initialize the Broadcast Channel
    socketService?.initializeBroadcastChannel();

    // Connect to the socket when the component mounts
    socketService?.connect();

    // Clean up the socket connection when the component unmounts
    return () => {
      socketService?.disconnect();
      socketService?.sendBroadcastMessage('disconnect');
    };
  }, []);

  // Render your component

  return <div>My Component</div>;
};

export default MyComponent;

Side Note: If you want to maintain the socket connection without closing it during a page reload. you need to store the connection state on the server and resuming the connection when the page reloads.

but this approach will be on the backend and it's complex enough TO NOT WASET YOUR TIME ON IT

the behavior you observed where the socket connection is closed and reestablished upon page reload is normal. I would argue.

Upvotes: 0

CharybdeBE
CharybdeBE

Reputation: 1843

It seems now that WebWorker are a more widespread technology that it could be use to share websocket.

As explain in this article https://crossbario.com/blog/Websocket-Persistent-Connections/ Webworker are Javascript that is running outside the "thread of the page" and thus are not deleted on page change. Note that it is running only in the same domain. You can also look at Kanaka's answer here How to maintain a WebSockets connection between pages? (2012-2017 answer beware)

Upvotes: 0

jfriend00
jfriend00

Reputation: 707228

It's impossible. You cannot keep the same socket.io or webSocket client connection when the page is changed or refreshed. The browser simply does not do that. When a new page is loaded or the current page is refreshed, all resources from the previous page are closed and freed by the browser, including socket.io/webSocket connections.

So, your server has to expect a new socket.io connection from the newly loaded page. If you use cookies or a server-side session object, you can identify, on the server, when a connection is coming from a client that you have previously seen and the server can then act accordingly to realize that this is just a previous client reconnecting on a new page.

Upvotes: 30

Related Questions