Schicke eine Nachricht an bestimmten Client mit socket.io und node.js
-
09-10-2019 - |
Frage
Ich arbeite mit socket.io und node.js und bis jetzt scheint es ziemlich gut, aber ich weiß nicht, wie eine Nachricht an einen bestimmten Client vom Server zu senden, so etwas wie folgt aus:
client.send(message, receiverSessionId)
Aber weder die .send()
noch die .broadcast()
Methoden scheinen mein Bedürfnis zu liefern.
Was ich als eine mögliche Lösung gefunden habe, ist, dass die .broadcast()
Methode akzeptiert als zweiten Parameter ein Array von SessionIds, an denen die Nachricht nicht senden, so dass ich ein Array mit allen SessionIds in diesem Moment mit dem Server verbunden passieren könnte , mit Ausnahme des einen möchte ich die Nachricht senden, aber ich fühle es muss eine bessere Lösung sein.
Irgendwelche Ideen?
Lösung
Nun müssen Sie den Client greifen für diese (Überraschung), können Sie entweder den einfachen Weg gehen:
var io = io.listen(server);
io.clients[sessionID].send()
Welche brechen kann, wage ich zu bezweifeln, aber es ist immer eine Möglichkeit, dass io.clients
vielleicht umziehen, so dass die mit Vorsicht oben verwenden
Oder Sie behalten den Überblick über die Kunden selbst, daher können Sie sie zu Ihrem eigenen clients
Objekt im connection
Zuhörer hinzufügen und sie im disconnect
Zuhörer entfernen.
würde ich das letztere verwenden, da je nach Anwendung, die Sie mehr Staat auf den Clients trotzdem haben möchten, so etwas wie clients[id] = {conn: clientConnect, data: {...}}
die Arbeit machen könnten.
Andere Tipps
Ivo Wetzel Antwort scheint nicht mehr in Socket.io 0.9 gültig.
Kurz gesagt müssen Sie jetzt speichern die socket.id
und Verwendung io.sockets.socket(savedSocketId).emit(...)
Nachrichten an sie senden.
Das ist, wie ich diese Arbeit in geclusterten Node.js Server:
Zuerst müssen Sie Redis Speicher als Speicher setzen, so dass Nachrichten Quer Prozesse gehen können:
var express = require("express");
var redis = require("redis");
var sio = require("socket.io");
var client = redis.createClient()
var app = express.createServer();
var io = sio.listen(app);
io.set("store", new sio.RedisStore);
// In this example we have one master client socket
// that receives messages from others.
io.sockets.on('connection', function(socket) {
// Promote this socket as master
socket.on("I'm the master", function() {
// Save the socket id to Redis so that all processes can access it.
client.set("mastersocket", socket.id, function(err) {
if (err) throw err;
console.log("Master socket is now" + socket.id);
});
});
socket.on("message to master", function(msg) {
// Fetch the socket id from Redis
client.get("mastersocket", function(err, socketId) {
if (err) throw err;
io.sockets.socket(socketId).emit(msg);
});
});
});
ich weggelassen, um den Clustering-Code hier, weil es diese mehr unübersichtlich macht, aber es ist trivial hinzuzufügen. Einfach alles des Arbeiter-Code hinzufügen. Weitere Dokumente hier http://nodejs.org/api/cluster.html
jede Steckdose verbindet ein Zimmer mit einer Socket-ID für einen Namen, so können Sie einfach
io.to(socket#id).emit('hey')
docs: http://socket.io/docs/rooms-and -namespaces / # default-Raum
Prost
Die einfachste, eleganteste Lösung
Es ist so einfach wie:
client.emit("your message");
Und das ist es.
Aber wie? Geben Sie mir ein Beispiel
Was wir alle brauchen ist in der Tat ein vollständiges Beispiel, und das ist, was folgt. Dies wird mit der neuesten Version socket.io (2.0.3) getestet und es ist auch mit modernen Javascript (die wir alle mit mittlerweile sein sollen).
Das Beispiel besteht aus zwei Teilen: einem Server und einem Client. Jedes Mal, wenn ein Client eine Verbindung, beginnt sie vom Server empfängt eine periodische Sequenznummer. Eine neue Sequenz wird für jeden neuen Client gestartet, so dass der Server Spur von ihnen einzeln zu halten hat. Das ist, wo die „Ich brauche eine Nachricht an einen bestimmten Client senden“ ins Spiel kommt. Der Code ist sehr einfach zu verstehen. Mal sehen es.
Server
server.js
const
io = require("socket.io"),
server = io.listen(8000);
let
sequenceNumberByClient = new Map();
// event fired every time a new client connects:
server.on("connection", (socket) => {
console.info(`Client connected [id=${socket.id}]`);
// initialize this client's sequence number
sequenceNumberByClient.set(socket, 1);
// when socket disconnects, remove it from the list:
socket.on("disconnect", () => {
sequenceNumberByClient.delete(socket);
console.info(`Client gone [id=${socket.id}]`);
});
});
// sends each client its current sequence number
setInterval(() => {
for (const [client, sequenceNumber] of sequenceNumberByClient.entries()) {
client.emit("seq-num", sequenceNumber);
sequenceNumberByClient.set(client, sequenceNumber + 1);
}
}, 1000);
Der Server startet auf Port 8000 auf eingehende Verbindungen zu hören. Wenn man ankommt, fügt es, dass neue Kunden zu einer Karte, so dass es den Überblick über seine Sequenznummer behalten kann. Es ist auch hört für diesen disconnect
Ereignis des Kunden, wenn sie es von der Karte entfernen werden.
Jede Sekunde wird ein Timer gebrannt. Wenn es der Fall ist, geht der Server über die Karte und sendet eine Nachricht an jeden Kunden mit seinen aktuellen Sequenznummer. Es erhöht dann sie und speichert die Nummer zurück in der Karte. Das ist alles, was es ist. Kinderleicht.
Client
Der Client-Teil ist sogar noch einfacher. Er verbindet nur mit dem Server und Streams für die seq-num
Nachricht, Druck an die Konsole jedes Mal, es ankommt.
client.js
const
io = require("socket.io-client"),
ioClient = io.connect("http://localhost:8000");
ioClient.on("seq-num", (msg) => console.info(msg));
Ausführen des Beispiel
Installieren Sie die benötigten Bibliotheken:
npm install socket.io
npm install socket.io-client
Führen Sie den Server:
node server
Öffnen andere Terminal-Fenster und Laich so viele Kunden, wie Sie wollen, indem Sie:
node client
Ich habe auch bereit, einen Kern mit dem vollständigen Code hier .
1.0 sollten Sie verwenden:
io.sockets.connected[socketid].emit();
Sie können mit
// Nachrichtens nur an den Absender-Client
socket.emit('message', 'check this');
// oder Sie können mit dem Sender an alle Zuhörer senden
io.emit('message', 'check this');
// send an alle Zuhörer außer dem Absender
socket.broadcast.emit('message', 'this is a message');
// oder Sie können es zu einem Raum senden
socket.broadcast.to('chatroom').emit('message', 'this is the message to all');
Wie auch immer Version, die wir verwenden, wenn wir nur console.log () das „io“ Objekt, das wir in unserer Server-Seite verwenden NodeJS Code, [z io.on ( ‚Verbindung‘, function (Buchse) {...});], können wir sehen, dass „io“ ist nur ein JSON-Objekt und gibt es viele untergeordnete Objekte, wo die Socket-ID und Socket-Objekte gespeichert werden <. / p>
Ich bin mit Socket.io Version 1.3.5, btw.
Wenn wir in dem io-Objekt aussehen, es enthält,
sockets:
{ name: '/',
server: [Circular],
sockets: [ [Object], [Object] ],
connected:
{ B5AC9w0sYmOGWe4fAAAA: [Object],
'hWzf97fmU-TIwwzWAAAB': [Object] },
Hier können wir die socketids "B5AC9w0sYmOGWe4fAAAA" usw. So sehen wir tun können,
io.sockets.connected[socketid].emit();
Auch auf weitere Inspektion können wir sehen, Segmente mögen,
eio:
{ clients:
{ B5AC9w0sYmOGWe4fAAAA: [Object],
'hWzf97fmU-TIwwzWAAAB': [Object] },
Wir können also einen Sockel von hier abrufen, indem Sie
io.eio.clients[socketid].emit();
Auch unter Motor haben wir,
engine:
{ clients:
{ B5AC9w0sYmOGWe4fAAAA: [Object],
'hWzf97fmU-TIwwzWAAAB': [Object] },
So, können wir auch schreiben,
io.engine.clients[socketid].emit();
Also, ich denke wir unser Ziel in einem der drei Wege erreichen kann ich oben aufgeführt,
- io.sockets.connected [SocketId] .emit (); ODER
- io.eio.clients [SocketId] .emit (); ODER
- io.engine.clients [SocketId] .emit ();
Sie können dies tun,
Auf Server.
global.io=require("socket.io")(server);
io.on("connection",function(client){
console.log("client is ",client.id);
//This is handle by current connected client
client.emit('messages',{hello:'world'})
//This is handle by every client
io.sockets.emit("data",{data:"This is handle by every client"})
app1.saveSession(client.id)
client.on("disconnect",function(){
app1.deleteSession(client.id)
console.log("client disconnected",client.id);
})
})
//And this is handle by particular client
var socketId=req.query.id
if(io.sockets.connected[socketId]!=null) {
io.sockets.connected[socketId].emit('particular User', {data: "Event response by particular user "});
}
Und auf dem Client, ist es sehr einfach zu handhaben.
var socket=io.connect("http://localhost:8080/")
socket.on("messages",function(data){
console.log("message is ",data);
//alert(data)
})
socket.on("data",function(data){
console.log("data is ",data);
//alert(data)
})
socket.on("particular User",function(data){
console.log("data from server ",data);
//alert(data)
})
io.sockets.sockets [socket.id] .emit (...) für mich gearbeitet in v0.9
Ab Version 1.4.5, müssen Sie bieten Ihnen eine richtig voran SocketId in io.to (). Ich war die SocketId nimmt der Kunde zu debuggen angemeldet und es war ohne Präfix so dass ich die Suche endete für immer, bis ich herausgefunden habe! So können Sie es wie könnte dies tun, wenn die Id Sie wird nicht vorangestellt:
io.to('/#' + socketId).emit('myevent', {foo: 'bar'});
Socket.IO ermöglicht es Ihnen, „Namensraum“ Ihre Steckdosen, die im Wesentlichen mittels Zuweisung verschiedene Endpunkte oder Pfade.
Dies könnte helfen: http://socket.io/docs/rooms-and-namespaces/