Nie ma wbudowanego sposobu, aby to zrobić. Więc najpierw przyjrzyjmy się, jak broadcast działa:
https://github.com/Automattic/socket.io/blob/master/lib/namespace.js 206 ... 221-224 ... 230
this.adapter.broadcast(packet, {
rooms: this.rooms,
flags: this.flags
});
Teraz wiemy, każda transmisja tworzy kilka obiektów temp wyszukiwań IndexOf argumenty plastry ... A następnie wywołuje metodę rozgłaszania adaptera. Pozwala spojrzeć na tym jednym:
https://github.com/Automattic/socket.io-adapter/blob/master/index.js 111-151
Teraz tworzymy nawet więcej obiektów tymczasowych i pętli przez wszystkich klientów w pokojach lub wszystkich klientów, jeśli nie został wybrany pokój. Pętla dzieje się w oddzwanianiu kodowania. Ten sposób można znaleźć tutaj:
https://github.com/socketio/socket.io-parser/blob/master/index.js
Ale co, jeśli nie wysyłamy nasze pakiety poprzez broadcast
ale do każdego klienta oddzielnie po pętli po pokojach i znalezienie klientów, które istnieją zarówno w pokoju A i pokojowej B?
socket.emit
zdefiniowano poniżej: https://github.com/Automattic/socket.io/blob/master/lib/socket.js
Co prowadzi do sposobu client.js
packet
: https://github.com/Automattic/socket.io/blob/master/lib/client.js
Każdy bezpośrednio emitowane pakiet zostanie oddzielnie kodowane, co znowu jest kosztowne. Ponieważ wysyłamy dokładnie ten sam pakiet do wszystkich użytkowników.
Aby odpowiedzieć na to pytanie:
albo zmienić klasę adaptera socket.io i zmiany sposobu nadawania, dodać swoje własne metody do prototypu lub przewróceniu własne zasilacza przez dziedziczenie z klasy adaptera). (var io = require('socket.io')(server, { adapter: yourCustomAdapter });
)
Można również zastąpić metody join
i leave
z zakresu socket.js
. Co jest dość wygodne, biorąc pod uwagę, że metody te nie są nazywane bardzo często i nie masz kłopotów z edycją przez wiele plików.
Socket.prototype.join = (function() {
// the original join method
var oldJoin = Socket.prototype.join;
return function(room, fn) {
// join the room as usual
oldJoin.call(this, room, fn);
// if we join A and are alreadymember of B, we can join C
if(room === "A" && ~this.rooms.indexOf("B")) {
this.join("C");
} else if(room === "B" && ~this.rooms.indexOf("A")) {
this.join("C");
}
};
})();
Socket.prototype.leave = (function() {
// the original leave method
var oldLeave = Socket.prototype.leave;
return function(room, fn) {
// leave the room as usual
oldLeave.call(this, room, fn);
if(room === "A" || room === "B") {
this.leave("C");
}
};
})();
A następnie transmitowane do C
jeśli chcesz nadawać do wszystkich użytkowników w A
i B
. To jest tylko przykładowy kod, można go dodatkowo poprawić, nie kodując w sposób trudny nazw pomieszczeń, ale używając tablicy lub obiektu, aby zapętlić możliwe kombinacje pokoi.
as Adapter do socket.broadcast.in("A").in("B").emit()
pracy:
var Adapter = require('socket.io-adapter');
module.exports = CustomAdapter;
function CustomAdapter(nsp) {
Adapter.call(this, nsp);
};
CustomAdapter.prototype = Object.create(Adapter.prototype);
CustomAdapter.prototype.constructor = CustomAdapter;
CustomAdapter.prototype.broadcast = function(packet, opts){
var rooms = opts.rooms || [];
var except = opts.except || [];
var flags = opts.flags || {};
var packetOpts = {
preEncoded: true,
volatile: flags.volatile,
compress: flags.compress
};
var ids = {};
var self = this;
var socket;
packet.nsp = this.nsp.name;
this.encoder.encode(packet, function(encodedPackets) {
if (rooms.length) {
for (var i = 0; i < rooms.length; i++) {
var room = self.rooms[rooms[i]];
if (!room) continue;
for (var id in room) {
if (room.hasOwnProperty(id)) {
if (~except.indexOf(id)) continue;
socket = self.nsp.connected[id];
if (socket) {
ids[id] = ids[id] || 0;
if(++ids[id] === rooms.length){
socket.packet(encodedPackets, packetOpts);
}
}
}
}
}
} else {
for (var id in self.sids) {
if (self.sids.hasOwnProperty(id)) {
if (~except.indexOf(id)) continue;
socket = self.nsp.connected[id];
if (socket) socket.packet(encodedPackets, packetOpts);
}
}
}
});
};
A w pliku app:
var io = require('socket.io')(server, {
adapter: require('./CustomAdapter')
});
zobaczyć to: http://stackoverflow.com/a/24145381/3842050 To może pomóc . – Blubberguy22
możesz to zrobić po stronie klienta, wysyłając do obu i tylko reagując na drugie przybycie na tego samego klienta ... – dandavis