Senden Sie zusätzliche Daten zur Socket-Verbindung


79

Wie sende ich am besten zusätzliche Daten bei Socket-Verbindung?

Klient:

socket.on('connect',function(){ 
//I'd like set some values and pass them up to the node server.
});

Node.js Server:

io.on('connection', function(client){
//I'd like to get the data here.
});

Zum Beispiel das Senden eines Benutzernamens oder einer E-Mail-Adresse usw.

Antworten:


66

Sie sollten Ihre Daten entweder in Verbindung oder beim Erstellen senden:

var s = io('http://216.157.91.131:8080/', { query: "foo=bar" });
s.connect();

var c = io.connect('http://216.157.91.131:8080/', { query: "foo=bar" });

Mit der neuen Version von socket.io wurden auf dem Server die Dinge geändert:

var io = require('socket.io')(server);

io.use(function(socket, next) {
  var handshakeData = socket.request;
  console.log("middleware:", handshakeData._query['foo']);
  next();
});

Ich habe andere Leute gesehen, die sagten, sie sollten verwenden socket.request.query, aber das funktioniert bei mir auf socket.io v1.7.2 nicht. Muss auf jeden Fall verwenden socket.request._query.
Kell


4
Für socket.io v1.7.3 musste ich socket.handshake.query(über diese Antwort ) verwenden.
Galen Long

Keine Möglichkeit, mehr als einen Parameter zu senden? Kennt jemand die Syntax? Fox Beispiel { query: "foo=bar", "bar=foo" }wird nicht funktionieren.
Adry

1
@ Miquel gelöst mit{query: 'var1='+foo+'&var2=bar'
Adry

31

Ich habe einen anderen Ansatz - sende ein Ereignis direkt nach dem Verbinden mit den Daten aus:

socket.on('connect',function(){ 
    // Send ehlo event right after connect:
    socket.emit('ehlo', data);
});

io.on('connection', function(client){
    // Receive ehlo event with data:
    client.on('ehlo', function(data) {
    });
});

Sie können eine Variable / ein Objekt halten und sagen, wenn kein ehloEreignis mit Daten vorhanden ist, werden die anderen Ereignisse ignoriert, bis sie ehlogesendet werden.

Wenn dies nicht zufriedenstellend ist, können Sie Daten direkt beim Herstellen der Verbindung senden. Ich werde den Code nicht kopieren, aber er lautet in dieser Antwort: https://stackoverflow.com/a/13940399/1948292


6
Dies ist ein guter Ansatz zum Übergeben von Daten zur Identifizierung eines Benutzers, z. B. eines Zugriffstokens. Möglicherweise möchten Sie auch behandeln, socket.on('reconnect', …)ob Ihr Server Daten benötigt, die nach einer Trennung möglicherweise nicht mehr bestehen bleiben.
Iain Collins

15

Die connectionEreignisse werden ausgelöst, sobald die TCP-Verbindung hergestellt ist. Es gibt keine Möglichkeit, etwas dazwischen zu senden.

Sie können einfach die erste vom Server gesendete Nachricht nehmen und die Daten in diese Nachricht einfügen. Ich würde dringend empfehlen, ein dünnes Protokoll dafür zu erstellen, damit Sie mehrere Arten von Nachrichten haben und diese verwenden, um zu bestimmen, wie der Code die Daten verarbeiten soll.

Dies wäre auch erweiterbarer, da es ziemlich einfach ist, eine generische Architektur dafür zu entwickeln. Wenn Sie darauf warten möchten, dass das userdatazuerst eingeht, können Sie Ihren Verbindungen einfach einen Status hinzufügen.


Hey Ivo, vielen Dank, dass du dich bei mir gemeldet hast. Können Sie mir etwas näher erläutern, wie Sie das erreichen, was Sie sagen? Danke noch einmal!
Dan

Grundsätzlich habe ich eine funktionierende Chat-App, mit der Sie an bestimmte Kunden senden können. Das Problem ist, dass ich die Sitzungs-ID nicht mit dem Benutzernamen abgleichen kann. Wenn Sie und ich uns also unterhielten, anstatt "Dan" und "Ivo" zu sagen, werden die Kunden-IDs angezeigt.
Dan

Können Sie mir ein bisschen mehr Informationen über Ihre Architektur / Ihren Code geben? Woher kommen die IDs und woher kommen die Namen? Kann die App nicht einfach eine Anfrage an den Server senden und nach den Benutzernamen fragen, die den IDs zugeordnet sind?
Ivo Wetzel

Benutzername würde von einer Datenbank kommen (dh nachdem sich ein Benutzer angemeldet hat). IDs stammen von client.sessionId. Um ehrlich zu sein, habe ich meine Lösung basierend auf einer Antwort implementiert, die Sie auf eine ähnliche Frage gegeben haben. Ich füge Clients hinzu, wenn sie (beim Verbinden) zu einem Array kommen, und entferne sie beim Trennen. Ich gebe die Client-IDs per Nachricht an den Client weiter und verbinde mich. Es funktioniert wirklich gut, also vielen Dank für diesen anderen Beitrag :) Wollen Sie damit sagen, dass ich die Datenbank anrufen und versuchen sollte, die Sitzungs-ID einem Feld in der Datenbank zuzuordnen?
Dan

@Dan: Speichern Sie einfach Ihre Benutzersitzung in Redis und speichern Sie den Schlüssel in einem Cookie im Benutzerbrowser. Holen Sie sich das Cookie auf Socket Connect und senden Sie es zurück an den Server.
Shripad Krishna

8

Dies ist mein Code zum Senden von Abfragedaten an nodejs und server.io Server Client

var socket = io.connect(window.location.origin,{query:'loggeduser=user1'});

io.sockets.on('connection', function (socket) {
    var endp = socket.manager.handshaken[socket.id].address;
    console.log("query... " +  socket.manager.handshaken[socket.id].query.user);
});

Abfrage ... Benutzer1



2

Dies ist mein Code für Socket Version 2.1.1

//client side
var socket = io.connect(window.location.origin,{query:'loggeduser=user1'});

// server side
io.socket.on('connection', function (socket) {
    console.log("loggeduser => " +  socket.handshake.query.loggeduser);
});

1

Ich gehe davon aus, dass Sie SSL verwenden werden.

Die Verwendung von Querystrings zum Senden vertraulicher Daten ist keine gute Sicherheitspraxis ( warum? ). Ich denke, wenn Sie nicht sensible Daten senden müssen, ist die Antwort von Miquel die schnellste und einfachste. Wenn Sie jedoch sensible Daten senden müssen, ist so etwas wie Daniel W. der beste Ansatz.

Für einen Authentifizierungsansatz können Sie sich dieses Github-Projekt ( socketio-auth ) ansehen, das Ihnen über die Tatsache hinaus, dass es derzeit nicht gewartet wird, eine gute Vorstellung davon geben kann, wie Sie mit dem Problem umgehen können.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.