简体   繁体   中英

How to detect if two clients/connections are on the same network (nodeJS / express / socket.io)

How would I go about detecting if a connection is on the same network as another connection? This could be from using http , express , socket.io or another library.

This would be used so that a user can quickly join a game hosted by another user in the same house. So other solutions to this would also be appreciated.

You can't because you won't have any way to determine the subnet.

Kind of like having the house number but not the street.

Network configuration is just too complicated, and in some (or even many) cases opaque¹, for you to use the network for this. Moreover, two people can be in the same house but on different networks (different mobile networks; one on WiFi and the other on mobile; even — in rare cases I'd think — different WiFi networks).

Instead, use prior art: User A creates some kind of unique game identifier (or your system does) and provides that information to User B so User B can join the game. (You may want to have User A confirm them before they're allowed in.) There are a million variations on that theme, but that's the basic, time-tested approach.


¹ Opaque from a browser perspective. Remember the browser sends the information Express sees on the server.

With some research I found a method to do this by looking at the Public IP address. I found a useful free API: http://ipify.org , but I wanted to keep it server side. This question answered how to get the IP from a request, but I decided to use request-ip .

Any thoughts on this approach? Obviously there is a very low chance of two networks having the same IPv4 address.

Here is a working example and below is the code.

index.js

const path = require('path');
const express = require("express");
const socket  = require('socket.io');
const requestIp = require('request-ip');

const app = express();
const server = app.listen(8080, () => console.log(`listening on port ${server.address().port}`));

const io = socket(server);

let networks = {};

app.get('/', (req, res) => {
  res.sendFile( path.join( __dirname, 'index.html') );
});

io.on('connection', function (socket) {
  let clientIP = requestIp.getClientIp(socket.request);
  console.log('New connection from ' + clientIP);
  
  if( networks[clientIP] == undefined ){ networks[clientIP] = []; };
  let network = networks[clientIP];
  
  network.push(socket);
  updateNetwork(network);
  
  socket.on('disconnect', function () {
    console.log('Disconnected ' + clientIP);

    network.splice(network.indexOf(socket), 1);
    updateNetwork(network);
  });
  
});

function updateNetwork(network){
  for( let socket of network ){
    socket.emit( 'network-clients', network.length );
  }
}

index.html

<html>
  <head>
    <meta charset="UTF-8">
    <script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/1.7.3/socket.io.js"></script>
    
    <script src="script.js" type="text/javascript"></script>
  </head>
  <body>
    <p>
      Clients Connected on the same network: <span id="network-clients">loading...</span>
    </p>
  </body>
  <script>
    let socket = io.connect(window.location.origin);

    socket.on('network-clients', (data) => {
      document.getElementById('network-clients').innerHTML = data;
    });
  </script>
</html>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM