it-swarm.com.de

Senden einer Nachricht an einen bestimmten verbundenen Benutzer mithilfe von webSocket?

Ich habe einen Code zum Senden einer Nachricht an alle Benutzer geschrieben:

Der verwendete Code: (kurz)

// websocket and http servers
var webSocketServer = require('websocket').server;

...
...
var clients = [ ];

var server = http.createServer(function(request, response) {
    // Not important for us. We're writing WebSocket server, not HTTP server
});
server.listen(webSocketsServerPort, function() {
  ...
});

var wsServer = new webSocketServer({
    // WebSocket server is tied to a HTTP server. 
    httpServer: server
});


    // This callback function is called every time someone
    // tries to connect to the WebSocket server
    wsServer.on('request', function(request) {
    ...
    var connection = request.accept(null, request.Origin); 
    var index = clients.Push(connection) - 1;
    ...

Bitte beachten Sie :

  • Ich habe keine Benutzerreferenz, sondern nur eine Verbindung.
  • Alle Benutzerverbindungen werden in einem array gespeichert.

Ziel: Nehmen wir an, der NodeJs-Server möchte eine Nachricht an einen bestimmten Client (John) senden.

Und hier ist die Frage:

  • Wie würde der NodeJs-Server wissen, welche Verbindung John hat?

    Der NodeJs-Server kennt John nicht einmal. Alles, was es sieht, sind die Verbindungen.

Daher glaube ich, dass ich Benutzer jetzt nicht nur nach ihrer Verbindung speichern sollte. Stattdessen muss ich ein Objekt - speichern, das die Zeichen userId und connection Objekt.

Und hier ist meine Idee:


  • Wenn die Seite vollständig geladen ist (Dom bereit), stellen Sie eine Verbindung zum NodeJs-Server her.

  • Wenn der NodeJs-Server eine Verbindung akzeptiert, generieren Sie eine eindeutige Zeichenfolge und senden Sie diese an den Client-Browser. Speichern Sie die Benutzerverbindung und die eindeutige Zeichenfolge in einem Objekt. z. B.{UserID:"6" , value :{connectionObject}}

  • Wenn diese Nachricht beim Kunden eintrifft, speichern Sie sie in einem versteckten Feld oder Cookie. (für zukünftige Anfragen an den NodeJs-Server)


Wenn der Server eine Nachricht an John senden möchte:

  • Suchen Sie Johns UserID im Wörterbuch und senden Sie eine Nachricht über die entsprechende Verbindung.

Bitte beachten Sie, dass hier (im Nachrichtenmechanismus) kein asp.net-Servercode angegeben ist. nur NodeJs.

Frage:

Ist das der richtige Weg? (oder habe ich etwas verpasst?)

64
Royi Namir

Dies ist nicht nur der richtige, sondern auch der einzige Weg. Grundsätzlich benötigt jede Verbindung eine eindeutige ID. Sonst können Sie sie nicht identifizieren, es ist so einfach.

Nun, wie Sie es darstellen, ist es eine andere Sache. Ein Objekt mit den Eigenschaften id und connection zu erstellen, ist ein guter Weg, dies zu tun (ich würde definitiv danach streben). Sie können das id auch direkt an das Verbindungsobjekt anhängen.

Denken Sie auch daran, dass, wenn Sie Kommunikation zwischen Benutzern wünschen, Sie auch die ID des Zielbenutzers senden müssen, d. H., Wenn Benutzer A eine Nachricht an Benutzer B senden möchte, muss A offensichtlich die ID von B kennen.

63
freakish

Hier ist ein einfacher Chat-Server für private/direkte Nachrichten.

package.json

{
  "name": "chat-server",
  "version": "0.0.1",
  "description": "WebSocket chat server",
  "dependencies": {
    "ws": "0.4.x"
  }
}

server.js

var webSocketServer = new (require('ws')).Server({port: (process.env.PORT || 5000)}),
    webSockets = {} // userID: webSocket

// CONNECT /:userID
// wscat -c ws://localhost:5000/1
webSocketServer.on('connection', function (webSocket) {
  var userID = parseInt(webSocket.upgradeReq.url.substr(1), 10)
  webSockets[userID] = webSocket
  console.log('connected: ' + userID + ' in ' + Object.getOwnPropertyNames(webSockets))

  // Forward Message
  //
  // Receive               Example
  // [toUserID, text]      [2, "Hello, World!"]
  //
  // Send                  Example
  // [fromUserID, text]    [1, "Hello, World!"]
  webSocket.on('message', function(message) {
    console.log('received from ' + userID + ': ' + message)
    var messageArray = JSON.parse(message)
    var toUserWebSocket = webSockets[messageArray[0]]
    if (toUserWebSocket) {
      console.log('sent to ' + messageArray[0] + ': ' + JSON.stringify(messageArray))
      messageArray[0] = userID
      toUserWebSocket.send(JSON.stringify(messageArray))
    }
  })

  webSocket.on('close', function () {
    delete webSockets[userID]
    console.log('deleted: ' + userID)
  })
})

Anleitung

Führen Sie zum Testen npm install Aus, um ws zu installieren. Führen Sie dann zum Starten des Chat-Servers node server.js (Oder npm start) Auf einer Registerkarte des Terminals aus. Führen Sie dann auf einer anderen Registerkarte des Terminals wscat -c ws://localhost:5000/1 Aus, wobei 1 Die Benutzer-ID des Verbindungsbenutzers ist. Führen Sie dann auf einer dritten Registerkarte des Terminals wscat -c ws://localhost:5000/2 Aus, und geben Sie 2 Ein, um eine Nachricht vom Benutzer 1 An ["1", "Hello, World!"] Zu senden.

Mängel

Dieser Chat-Server ist sehr einfach.

  • Beharrlichkeit

    Es werden keine Nachrichten in einer Datenbank wie PostgreSQL gespeichert. Der Benutzer, an den Sie eine Nachricht senden, muss also mit dem Server verbunden sein, um sie zu empfangen. Andernfalls geht die Nachricht verloren.

  • Sicherheit

    Es ist unsicher.

    • Wenn ich die URL des Servers und die Benutzer-ID von Alice kenne, kann ich mich als Alice ausgeben, dh eine Verbindung zum Server als sie herstellen, sodass ich ihre neuen eingehenden Nachrichten empfangen und Nachrichten von ihr an jeden Benutzer senden kann, dessen Benutzer-ID ich auch kenne. Um die Sicherheit zu erhöhen, ändern Sie den Server so, dass er Ihr Zugriffstoken (anstelle Ihrer Benutzer-ID) beim Herstellen der Verbindung akzeptiert. Anschließend kann der Server Ihre Benutzer-ID von Ihrem Zugriffstoken abrufen und Sie authentifizieren.

    • Ich bin nicht sicher, ob es eine WebSocket Secure-Verbindung (wss://) Unterstützt, da ich sie nur auf localhost getestet habe, und ich bin nicht sicher, wie ich eine sichere Verbindung von localhost.

31
ma11hew28

Ich möchte mitteilen, was ich getan habe. Hoffe, es verschwendet nicht deine Zeit.

Ich habe eine Datenbanktabelle mit Feld-ID, IP, Benutzername, Anmeldezeit und Abmeldezeit erstellt. Wenn sich ein Benutzer bei logintime anmeldet, wird unixtimestamp unix korrekt sein. Wenn die Verbindung in der Websocket-Datenbank hergestellt wird, wird nach der längsten Anmeldezeit gesucht. Es wird der angemeldete Benutzer kommen.

Und wenn sich der Benutzer abmeldet, wird die korrekte Abmeldezeit gespeichert. Der Benutzer wird derjenige, der die App verlassen hat.

Bei jeder neuen Nachricht werden Websocket-ID und IP verglichen und der zugehörige Benutzername wird angezeigt. Es folgen Beispielcode ...

// when a client connects
function wsOnOpen($clientID) {
      global $Server;
      $ip = long2ip( $Server->wsClients[$clientID][6] );

      require_once('config.php');
      require_once CLASSES . 'class.db.php';
      require_once CLASSES . 'class.log.php';

      $db = new database();
      $loga = new log($db);

      //Getting the last login person time and username
      $conditions = "WHERE which = 'login' ORDER BY id DESC LIMIT 0, 1";
      $logs = $loga->get_logs($conditions);
      foreach($logs as $rows) {

              $destination = $rows["user"];
              $idh = md5("$rows[user]".md5($rows["time"]));

              if ( $clientID > $rows["what"]) {
                      $conditions = "ip = '$ip', clientID = '$clientID'  

                      WHERE logintime = '$rows[time]'";
                      $loga->update_log($conditions);
             }
      }
      ...//rest of the things
} 
1
tashi

interessanter Beitrag (ähnlich dem, was ich tue). Wir erstellen eine API (in C #), um Dispenser mit WebSockets zu verbinden. Für jeden Dispenser erstellen wir ein ConcurrentDictionary, in dem das WebSocket und die DispenserId gespeichert sind. Auf diese Weise kann jeder Dispenser problemlos ein WebSocket erstellen und anschließend ohne Thread-Probleme verwenden (wobei bestimmte Funktionen aufgerufen werden) auf dem WebSocket wie GetSettings oder RequestTicket). Der Unterschied für Sie besteht in der Verwendung von ConcurrentDictionary anstelle eines Arrays zum Isolieren der einzelnen Elemente (dies wurde in Javascript nie versucht). Freundliche Grüße,

0
wolf354