title: Socket.io double events, solved for connect BUT not disconnect
body: <p>I'm new to socket.io and next.JS. After getting socket.io integrated in to Next I noticed connect code was firing twice, doubling my connection count (which I need to be accurate).</p>
  <p>I googled a lot but did not find a solution that worked, including <em>socket.once('connect')</em>. I fixed this by creating a <strong>manual</strong> connect event and emitting from the client on startup. I can now see an accurate connection count as long as no one disconnects.</p>
  <p>As for disconnecting I'm seeing the same problem, where disconnect fires twice per user, but I don't know how to manually emit on the client whenever a disconnection happens.</p>
  <p>Any advice on how to emit a manual disconnect from the client?</p>
  <p>Or a new approach? Maybe use a set to hold client ids instead of incrementing an int? Might be bad for performance with the repeated collection counting though (each user will be accessing the total count very often, maybe every second).</p>
  <p><strong>server code</strong>:</p>
  <pre><code>const SERVER_STATE = {
    totalConnections: 0
  } 
  
  // socket.io server
  io.on('connection', socket =&gt; {
  
    socket.once('userConnectOnce', () =&gt; {
      SERVER_STATE.totalConnections++;
      socket.emit('message', `Welcome from server. There are a total of ${SERVER_STATE.totalConnections} connections.`);
      socket.broadcast.emit('message', `New user joined. There are a total of ${SERVER_STATE.totalConnections} connections.`);
    });
  
    socket.once('disconnect', () =&gt; {       // this fires more than once
      SERVER_STATE.totalConnections--;
      socket.broadcast.emit('message', `Other user disonnected. There are now ${SERVER_STATE.totalConnections} connections.`);
    });
  
  });
  </code></pre>
  <p><strong>client code</strong>:</p>
  <pre><code>const Index = () =&gt; {
    const socket = useSocket('message', (data) =&gt; {
      console.log(data);
    });
  
    socket.emit('userConnectOnce', 'client-initiated userConnectOnce');
  
    return (
      &lt;&gt;&lt;/&gt;
    );
  };
  </code></pre>
  <p>Note: <strong>useSocket()</strong> is custom hook from the next examples repo to wrap socket.on() inside useEffect() and return the socket. I can't find the link, and not sure its relevant, but here's some of the code:</p>
  <pre><code>import { useEffect } from 'react';
  import io from 'socket.io-client';
  
  const socket = io();
  
  export default function useSocket(eventName, cb) {
    useEffect(() =&gt; {
      socket.on(eventName, cb);
  
      return function socketCleanup() {
        socket.off(eventName, cb);
      }
    }, [eventName, cb]);
  
    return socket;
  }
  </code></pre>