Wyślij wiadomość do konkretnego klienta z socket.io i węzeł.js
Pracuję z socket.io i węzeł.js i do tej pory wydaje się całkiem nieźle, ale nie wiem jak wysłać wiadomość z serwera do konkretnego klienta, coś w tym stylu:
client.send(message, receiverSessionId)
Ale ani .send()
Ani .broadcast()
metody nie wydają się zaspokajać moich potrzeb.
To, co znalazłem jako możliwe rozwiązanie, to to, że metoda .broadcast()
akceptuje jako drugi parametr tablicę identyfikatorów sesji, do których nie wysyła wiadomości, więc mogę przekazać tablicę ze wszystkimi identyfikatorami sesji podłączonymi do tego moment na serwer, z wyjątkiem tego, który chciałbym wysłać wiadomość, ale uważam, że musi być lepsze rozwiązanie.
11 answers
Cóż, musisz złapać za to Klienta (niespodzianka), możesz albo pójść prostą drogą:
var io = io.listen(server);
io.clients[sessionID].send()
Które mogą się zepsuć, nie wątpię w to, ale zawsze jest możliwość, że io.clients
może się zmienić, więc używaj powyższego z ostrożnością
Lub śledzisz klientów samodzielnie, dlatego dodajesz je do własnego obiektu clients
w detektorze connection
i usuwasz je w detektorze disconnect
.
Użyłbym tego drugiego, ponieważ w zależności od aplikacji możesz chcieć miej więcej informacji na temat klientów i tak, więc coś w stylu clients[id] = {conn: clientConnect, data: {...}}
może załatwić sprawę.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-01-10 14:14:13
Odpowiedź Ivo Wetzela nie wydaje się być aktualna w Socket.io 0.95%
W skrócie musisz teraz zapisać socket.id
i użyć io.sockets.socket(savedSocketId).emit(...)
, Aby wysłać do niego wiadomości.
Tak to działa w clustered Node.serwer js:
Najpierw musisz ustawić Redis store jako store, aby wiadomości mogły przejść przez procesy:
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);
});
});
});
Pominąłem tutaj Kod klastrowy, ponieważ sprawia, że jest to bardziej zaśmiecone, ale to jest trywialne dodać. Wystarczy dodać wszystko do kodu pracownika. Więcej docs here http://nodejs.org/api/cluster.html
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-05-09 12:01:40
Każde gniazdo łączy się z pokojem z identyfikatorem gniazda dla nazwy, więc możesz po prostu
io.to(socket#id).emit('hey')
Docs: http://socket.io/docs/rooms-and-namespaces/#default-room
Cheers
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-12-03 11:28:38
Najprostsze, najbardziej eleganckie rozwiązanie
To tak proste jak:client.emit("your message");
I to wszystko.
Ale jak? Daj mi przykładTo, czego wszyscy potrzebujemy, to w rzeczywistości pełny przykład,i to jest to, co następuje. Jest to testowane z najnowszymi socket.io Wersja (2.0.3) i jest również przy użyciu nowoczesnego Javascript(który powinniśmy wszyscy używać teraz).
Przykład składa się z dwóch części: serwera i klienta. Ilekroć Klient się połączy, zaczyna odbierać z serwera numer sekwencji okresowej. Dla każdego nowego klienta uruchamiana jest nowa sekwencja, więc serwer musi śledzić je indywidualnie. To jest miejsce, gdzie "muszę wysłać wiadomość do konkretnego klienta" wchodzi w grę. Kod jest bardzo prosty do zrozumienia. Zobaczmy.
Serwer
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);
Serwer zaczyna nasłuchiwać na porcie 8000 dla połączeń przychodzących. Kiedy ktoś przybywa, dodaje nowego klienta do mapy, aby mógł śledzić jego numer porządkowy. Nasłuchuje również zdarzenia disconnect
tego klienta, kiedy usunie je z mapy.
Co sekundę uruchamiany jest timer. Kiedy to zrobi, serwer przechodzi przez mapę i wysyła wiadomość do każdego klienta z jego aktualnym numerem sekwencji. Następnie zwiększa go i zapisuje numer z powrotem na mapie. To wszystko. Bułka z masłem.
Klient
Część klienta jest jeszcze prostsza. Po prostu łączy się z serwerem i słucha seq-num
wiadomość, drukując ją na konsoli za każdym razem, gdy przybywa.
client.js
const
io = require("socket.io-client"),
ioClient = io.connect("http://localhost:8000");
ioClient.on("seq-num", (msg) => console.info(msg));
Uruchamianie przykładu
Zainstaluj wymagane biblioteki:
npm install socket.io
npm install socket.io-client
Uruchom Serwer:
node server
Otwórz inne okna terminala i odradzaj tylu klientów, ilu chcesz, uruchamiając:
node client
przygotowałem również gist z pełnym kodem tutaj .
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-10-01 15:32:37
W 1.0 należy użyć:
io.sockets.connected[socketid].emit();
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-02-27 16:37:33
Możesz użyć
//wyślij wiadomość tylko do sender-client
socket.emit('message', 'check this');
/ / lub możesz wysłać do wszystkich słuchaczy, w tym do nadawcy
io.emit('message', 'check this');
//Wyślij do wszystkich słuchaczy z wyjątkiem nadawcy
socket.broadcast.emit('message', 'this is a message');
/ / lub możesz wysłać go do pokoju
socket.broadcast.to('chatroom').emit('message', 'this is the message to all');
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-06-25 07:25:06
Niezależnie od wersji, której używamy, jeśli tylko konsolujemy.log() obiekt "io", którego używamy w kodzie nodejs po stronie serwera, [np. io.on ('connection', function (socket) {...});], widzimy, że " io " jest tylko obiektem json i istnieje wiele obiektów potomnych, w których przechowywane są Socket id i socket objects.
Używam socket.io Wersja 1.3.5, btw.
Jeśli spojrzymy w obiekt io, zawiera on,
sockets:
{ name: '/',
server: [Circular],
sockets: [ [Object], [Object] ],
connected:
{ B5AC9w0sYmOGWe4fAAAA: [Object],
'hWzf97fmU-TIwwzWAAAB': [Object] },
Tutaj możemy zobaczyć skarpety "B5AC9w0sYmOGWe4fAAAA" itp. Więc możemy do,
io.sockets.connected[socketid].emit();
Ponownie, przy dalszej kontroli możemy zobaczyć segmenty takie jak,
eio:
{ clients:
{ B5AC9w0sYmOGWe4fAAAA: [Object],
'hWzf97fmU-TIwwzWAAAB': [Object] },
Więc możemy odzyskać Gniazdo, wykonując
io.eio.clients[socketid].emit();
Również, pod silnikiem mamy,
engine:
{ clients:
{ B5AC9w0sYmOGWe4fAAAA: [Object],
'hWzf97fmU-TIwwzWAAAB': [Object] },
Więc możemy też napisać,
io.engine.clients[socketid].emit();
Więc, myślę, że możemy osiągnąć nasz cel w dowolnym z 3 sposobów wymienionych powyżej,
- io.gniazda.podłączony [socketid].emitować(); Lub
- io.eio.klientów [socketid].emitować(); Lub
- io.silnik.klientów [socketid].emit ();
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-06-17 10:30:10
Możesz to zrobić
Na serwerze.
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 "});
}
I na kliencie, jest bardzo łatwy w obsłudze.
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)
})
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-06-07 12:28:27
Począwszy od wersji 1.4.5, upewnij się, że podajesz poprawnie poprzedzony socketId w io.to (). Brałem socketId, który klient zalogował się do debugowania i był bez prefiksu, więc skończyło się na szukaniu w nieskończoność, aż się dowiedziałem! Możesz więc zrobić to w ten sposób, jeśli identyfikator, który posiadasz, nie jest poprzedzony prefiksem:
io.to('/#' + socketId).emit('myevent', {foo: 'bar'});
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-07-22 11:23:47
Io. sockets. sockets[socket.id]. emit(...) działało u mnie w v0. 9
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-02-01 12:09:02
Socket.IO pozwala na "Przestrzeń nazw" gniazd, co zasadniczo oznacza przypisywanie różnych punktów końcowych lub ścieżek.
To może pomóc: http://socket.io/docs/rooms-and-namespaces/
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-01-12 16:18:42