Ich habe einen Code zum Senden einer Nachricht an alle Benutzer geschrieben:
// 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 gespeichert
array
.
Ziel : Angenommen, der Node.js-Server möchte eine Nachricht an einen bestimmten Client (John) senden. Wie würde der NodeJs-Server wissen, welche Verbindung John hat? Der Node.js-Server kennt John nicht einmal. Alles, was es sieht, sind die Verbindungen.
Daher glaube ich, dass ich Benutzer jetzt nicht nur über ihre Verbindung speichern sollte, sondern stattdessen ein Objekt speichern muss, das das userId
und das connection
Objekt enthält.
Idee:
Wenn die Seite vollständig geladen ist (DOM-fähig), stellen Sie eine Verbindung zum Node.js-Server her.
Wenn der Node.js-Server eine Verbindung akzeptiert, generieren Sie eine eindeutige Zeichenfolge und senden Sie sie an den Client-Browser. Speichern Sie die Benutzerverbindung und die eindeutige Zeichenfolge in einem Objekt. z.B
{UserID:"6", value: {connectionObject}}
Wenn diese Nachricht auf der Clientseite 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 aufgerufen wird. nur NodeJs. *
Frage:
Ist das der richtige Weg?
quelle
SOCKETS = {};
auf der Serverseite zu belassen und einer Liste einen Socket für eine Give-ID hinzuzufügen, dhSOCKETS["John"] = [];
undSOCKETS["John"].push(conn);
. Sie werden das wahrscheinlich brauchen, da ein Benutzer mehrere Registerkarten öffnen kann.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
npm install
zum Testen die Installation ausws
. Um den Chat-Server zu starten, führen Sie ihn auf einer Registerkarte des Terminals ausnode server.js
(odernpm start
). Dann in einem anderen Terminal - Registerkarte laufenwscat -c ws://localhost:5000/1
, wo1
ist die Verbindungs Benutzer-ID des Benutzers. Dann wird in einem dritten Terminal - Registerkarte laufenwscat -c ws://localhost:5000/2
und dann eine Nachricht von Benutzer senden geben .2
1
["1", "Hello, World!"]
Mängel
Dieser Chat-Server ist sehr einfach.
Beharrlichkeit
Es werden keine Nachrichten in einer Datenbank wie PostgreSQL gespeichert. Daher muss der Benutzer, an den Sie eine Nachricht senden, 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 ebenfalls kenne. Um die Sicherheit zu erhöhen, ändern Sie den Server so, dass er beim Herstellen einer Verbindung Ihr Zugriffstoken (anstelle Ihrer Benutzer-ID) 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 (
wss://
) -Verbindung unterstützt, da ich sie nur getestet habelocalhost
, und ich bin nicht sicher, wie ich eine sichere Verbindung herstellen solllocalhost
.quelle
Für Benutzer mit
ws
Version 3 oder höher. Wenn Sie die Antwort von @ ma11hew28 verwenden möchten, ändern Sie diesen Block einfach wie folgt.webSocketServer.on('connection', function (webSocket) { var userID = parseInt(webSocket.upgradeReq.url.substr(1), 10)
webSocketServer.on('connection', function (webSocket, req) { var userID = parseInt(req.url.substr(1), 10)
ws
Das Paket hat upgradeReq verschoben, um ein Objekt anzufordern, und Sie können den folgenden Link für weitere Details überprüfen.Referenz: https://github.com/websockets/ws/issues/1114
quelle
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 anmeldet, ist logintime unixtimestamp unix korrekt. Und wenn die Verbindung in der Websocket-Datenbank gestartet wird, wird nach der größten Anmeldezeit gesucht. Es wird kommen Benutzer angemeldet.
Und wenn sich der Benutzer abmeldet, wird die korrekte Abmeldezeit gespeichert. Der Benutzer wird zu dem, der die App verlassen hat.
Immer wenn eine neue Nachricht eingeht, 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 }
quelle
interessanter Beitrag (ähnlich wie ich es mache). Wir erstellen eine API (in C #), um Spender mit WebSockets zu verbinden. Für jeden Spender erstellen wir ein ConcurrentDictionary, in dem WebSocket und DispenserId gespeichert sind, damit jeder Dispenser auf einfache Weise ein WebSocket erstellen und anschließend ohne Thread-Probleme verwenden kann (Aufruf bestimmter Funktionen) auf dem WebSocket wie GetSettings oder RequestTicket). Der Unterschied für Sie ist beispielsweise die Verwendung von ConcurrentDictionary anstelle eines Arrays zum Isolieren jedes Elements (dies wurde in Javascript nie versucht). Freundliche Grüße,
quelle