NodeJS: client à client via serveur

J’ai un petit problème avec l’envoi de données d’un client à un client via le serveur (pour éviter d’écouter les ports sur le client).

J’ai un serveur comme celui-ci:

var net = require("net"); var server = net.createServer(function(socket) { socket.on("data", function(data) { }); }); server.listen(port); 

Maintenant, je veux redirect les données d’un client vers l’autre client via le serveur. Mais je n’ai aucune idée de la manière de procéder car je ne sais pas comment résoudre une connexion hors d’une autre connexion.

Est-ce que quelqu’un sait comment je peux faire ça?

Vous pouvez enregistrer tous les clients dans un tableau simple et l’envoyer à chacun des clients sans l’identifiant du socket du client. donc chaque client ne recevra que les autres. alors vous pouvez l’adresser par l’identifiant du client:

 var net = require("net"); var clients = {}; var server = net.createServer(function(socket) { socket.on("connect", function () { // Get the socket id of the connected client var socketId = null; // Get the client socket var clientSocket = null; clients[socketId] = clientSocket; }); // Socket is the client socket.on("data", function(data) { var d = JSON.parse(data); if (d.client) { if (!clients[d.client.id]) { // Client doesn't exists return; } // Send messages to the client with the saved socket clients[d.client.id].send(d.data); } }); socket.on("end", function () { // Get the socket id of the disconnected client var socketId = null; delete clients[socketId]; }); }); server.listen(port); 

Je sais travailler avec socket.io et je vous recommande fortement de travailler avec cela aussi ..

Dans socket.io, cela pourrait ressembler à ceci:

 var io = require('socket.io')(80); // Store all your clients var clients = {}; // Example: http://socket.io/docs/#using-with-node-http-server io.on("connection", function (socket) { // Save the client to let other client use it clients[socket.id] = socket; // Send all the clients except the self client sendClient(socket); // Client disconnected or connection somehow lost socket.on("disconnect", function () { // Remove the client delete clients[socket.id]; }); // Simple event to proxy to another client socket.on("proxy", function (client) { if (clients[client.id]) clients[client.id].emit("event", client.data); }); }); // Send all the clients and exclude the given socket id function sendClient(socket) { var list = []; for (let socketId in clients) { if (!clients.hasOwnProperty(socketId)) continue; if (socketId == socket.id) continue; list.push(socketId); } socket.emit("clients", list); } 

et le client pourrait être (en utilisant socket-io.client):

 var io = require('socket.io-client'); var socket = io("http://localhost:80"); socket.on("connect", function () { }); socket.on("clients", function (clients) { // We have all the clients clients.forEach(function (clientId) { var client = {}; client.id = clientId; client.data = {blah: 1}; socket.emit("proxy", client); }); }); socket.on("disconnect", function () { }); 

Vous devez stocker les connexions quelque part, comme dans un tableau (si vous en avez plus de deux) ou un object contenant un identifiant unique que vous pouvez utiliser pour rechercher facilement le socket de destination. Par exemple:

 var sockets = []; net.createServer(function(s) { // Add the socket to our connected socket list sockets.push(s); // Automatically remove the socket when it disconnects s.on('close', function() { sockets.splice(sockets.indexOf(s), 1); }); // How you determine the destination socket is up to you var destSocket = ...; // This pipes data between the current socket and the // destination socket (both directions) but does not automatically // close one socket when the other socket closes s.pipe(destSocket, { end: false }) .pipe(s, { end: false }); }).listen(port); 

Vous pourriez rendre cela plus compliqué que cela si votre application doit être plus flexible. Par exemple, vous pouvez trouver le socket de destination en lisant une seule ligne (terminée par \n ) à partir du socket source lors de la connexion, qui contient l’adresse IP du socket de destination. Ensuite, au lieu d’un tableau, vous avez un object indexé sur l’adresse IP de chaque socket, vous permettant de trouver facilement le socket de destination approprié.

Ou peut-être que chaque socket source envoie à la fois un “identifiant d’utilisateur” et une destination demandée “identifiant d’utilisateur”. À ce stade, vous pouvez aussi simplement faire de la ligne unique initiale une chaîne JSON suivie de \n , afin que le client puisse envoyer un nombre quelconque de parameters nécessaires pour que le pont se produise.

Un exemple de solution plus complexe utilisant un en-tête JSON:

 var sockets = Object.create(null); net.createServer(function(s) { s.on('error', function(err) { }); readJSON(s, function(err, result) { var dest; // Check if socket closed while reading our JSON header if (!s.writable) return; // Immediately close the socket when either: // * We receive a malformed JSON header // * Or the source socket id is already used // * Or the destination socket is not connected // You could extend this check more if you wanted, for example // to perform authentication. if (err || typeof result !== 'object' || result === null || (typeof result.id !== 'ssortingng' && typeof result.id !== 'number') || (typeof result.destId !== 'ssortingng' && typeof result.destId !== 'number') || sockets[result.id] || !(dest = sockets[result.destId]) || dest.busy) return s.destroy(); var id = result.id; sockets[id] = s; // Set a flag on each socket to allow exclusive communication // between connected sockets s.busy = dest.busy = true; // Hook the sockets up together, allowing the closing of either // socket to close the other s.pipe(dest).pipe(s); s.on('close', function() { delete sockets[id]; }); }); }).listen(port); function readJSON(s, cb) { var buf = ''; (function read() { var chunk = s.read(); if (chunk === null) return s.once('readable', read); for (var i = 0; i < chunk.length; ++i) { // 10 === LF (\n) if (chunk[i] === 10) { // Check if there is leftover data that is not // a part of our JSON message that we need to // put back onto the socket if (i < (chunk.length - 1)) s.unshift(chunk.slice(i + 1)); buf += chunk.toString('utf8', 0, i); var result = tryParseJSON(buf); if (result instanceof Error) cb(result); else cb(null, result); return; } } buf += chunk.toString('utf8'); // TODO: implement `buf.length` check to make sure we don't // buffer indefinitely })(); } // This is merely an optimization since v8 currently does not // optimize any functions containing a `try-catch` or `try-finally`. // By isolating the `try-catch` needed for JSON parsing, we can limit // the deoptimization. function tryParseJSON(str) { try { return JSON.parse(str); } catch (ex) { return ex; } } 

Exemple de client pour la solution ci-dessus:

 var s = net.connect(port, function() { // Send our header s.write(JSON.ssortingngify({ id: '123', destId: '456' }) + '\n'); s.end('Hello Dave!'); }).on('error', function(err) { // This should fire when the server rejects our request // due to one of the request checks failing console.log('Uh oh: ' + err); }); 

Une fois que ce client se connecte (en supposant qu'un autre socket identifié comme 456 est déjà connecté), le socket de destination devrait voir les données Hello Dave! . Ensuite, les deux sockets se fermeront.