How to disable socket.io when the tab is not in use as it is occupying a lot of RAM and Too many connections issue

I just want to get live data from Mysql DB on the UI Reactjs. So that the user need not to refresh it always. After looking over some posts end up creating a socket.io connection so that the client can speak to the server. This is what I tried to get into:

server.js

const express = require("express");
const http = require("http");
const socketIo = require("socket.io");
var assert = require('assert');
const port = process.env.PORT || 4001;
const index = require("./routes/index");
const app = express();
app.use(index);
const server = http.createServer(app);
const io = socketIo(server);
const mysql = require('mysql');

var startDate ;
var endDate ;
var loopVariable = 1;

io.on("connection", (socket) => {
   console.log("New client connected");
   const con = mysql.createConnection({
      host: 'localhost',
      user: 'root',
      password: 'root',
      database: 'localstatus',
      debug: false,
    });
   console.log('Connection established       ',(loopVariable++));
   socket.on("FromUI", (data) => {
        startDate = data.startDate;
        endDate = data.endDate;
    });
    
   var initial_result;
   setInterval(() => {
    
   con.query('SELECT * FROM table where start_time BETWEEN ? and ?', [ startDate, endDate ],(err,rows) => 
   {

    if(err) {
         console.log ('error', err.message, err.stack)
    }else {
        
    }
   if(JSON.stringify(rows) === JSON.stringify(initial_result)){
       
   }else{
        if(Changed(initial_result, rows)) { 
        
        var result = [];
        for (var row in rows) {
        var results = [];
            results.push({
                Id: rows[row].id, 
                status: rows[row].t_status,
                });
            result.push({ returnValue:"true",
                        object: {Id: rows[row].id, 
                        status: rows[row].t_status,
                        }});
        }
        socket.emit('FromAPI', result); 
        }
        initial_result = rows;  
   }    
  })
  
  function Changed(pre, now) {
    if (pre != now)
    {
        return true 
    }else{
        return false 
    }}   
   }, 1000);
    
   socket.on('disconnect', function() {
     socket.disconnect();
     loopVariable--;
   });
});
server.listen(port, () => console.log(`Listening on port ${port}`));

client.js

import React, { useState, useEffect, Component } from "react";
import socketIOClient from "socket.io-client";
import TableUsingReactTable from "./TableUsingReactTable.js";
const ENDPOINT = "http://localhost:4001";

export default function App(){
 const [response, setResponse] = useState([]);
  useEffect(() => {
    const socket = socketIOClient(ENDPOINT);
    try{
    socket.on("FromAPI", data => {
        setResponse(data);
    });
  }catch (error) {
      console.log(error);
  }
    return () => {
      socket.on("disconnect")
      socket.disconnect();
    };
  }, []);
  console.log(response)
return (<TableUsingReactTable response={response}></TableUsingReactTable>)
}

I think the socket gets disconnected when the tab gets closed, but what happens when is tab is not in use? And how to disable it when not in use? Even when all the tabs are closed then also the RAM increases. How to reduce the RAM when sockets get closed? And how does socket.io behave when at the same time many hit the URL? Moreover, sometimes I did face the issue as:

  code: 'ER_CON_COUNT_ERROR',
  errno: 1040,
  sqlMessage: 'Too many connections',
  sqlState: undefined,
  fatal: true

How to handle this case too? I m new to this and not understanding how to proceed further. Can someone help me with this? Thanks a lot.

Answer

Firstly, you don’t actually need Socket.IO for this use case. Server-Sent Events/EventSource API are fine for this, as you’re only sending data in one direction. This gives you the benefit of not needing to load Socket.IO libraries.

Now, the real problem is that you’re creating a separate MySQL connection for each individual client. Rather than calling mysql.createConnection() every time a new client connects, you can connect to your database once. (There are situations where this isn’t appropriate, but since you’re just doing some basic SELECT queries, this is fine.)

Leave a Reply

Your email address will not be published. Required fields are marked *