Non esiste un modo per farlo. Quindi, prima diamo un'occhiata a come funziona la trasmissione:
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
});
Ora sappiamo ogni trasmissione crea un gruppo di oggetti temporanei, le ricerche indexOf, argomenti fette ... E poi chiama il metodo di trasmissione dell'adattatore. Diamo un'occhiata a che uno:
https://github.com/Automattic/socket.io-adapter/blob/master/index.js 111-151
Ora ci stanno creando ancora più oggetti temporanei e scorrere tutti i clienti nelle camere o tutti i clienti se c'è spazio è stato selezionato. Il ciclo si verifica nel callback di codifica. Tale metodo può essere trovato qui:
https://github.com/socketio/socket.io-parser/blob/master/index.js
Ma cosa succede se non stiamo inviando i nostri pacchetti tramite broadcast
ma ad ogni cliente separatamente dopo il ciclo attraverso le stanze e trovare clienti che esistono sia nella stanza A e B camera?
socket.emit
è definito qui: https://github.com/Automattic/socket.io/blob/master/lib/socket.js
che ci porta al metodo del client.js
packet
: https://github.com/Automattic/socket.io/blob/master/lib/client.js
Ciascun pacchetto direttamente emessa verranno codificati separatamente, che a sua volta, è costoso. Perché stiamo inviando lo stesso identico pacchetto a tutti gli utenti.
Per rispondere alla tua domanda:
O cambiare la classe di adattatori socket.io e modificare il metodo di trasmissione, aggiungere i propri metodi per il prototipo o rotolare il proprio adattatore ereditando dalla classe adattatore). (var io = require('socket.io')(server, { adapter: yourCustomAdapter });
)
Oppure sovrascrivere i metodi join
e leave
dello socket.js
. Il che è piuttosto conveniente considerando che quei metodi non vengono chiamati molto spesso e non si ha il fastidio di modificare attraverso più file.
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");
}
};
})();
E poi trasmesso al C
se si desidera trasmettere a tutti gli utenti in A
e B
. Questo è solo un codice di esempio, è possibile migliorare ulteriormente non codificando con difficoltà i nomi delle room, ma usando una matrice o un oggetto invece di eseguire il loop su possibili combinazioni di stanze.
come adattatore personalizzato per rendere socket.broadcast.in("A").in("B").emit()
lavoro:
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);
}
}
}
});
};
E nel file app:
var io = require('socket.io')(server, {
adapter: require('./CustomAdapter')
});
vedere questo: http://stackoverflow.com/a/24145381/3842050 Potrebbe aiutare . – Blubberguy22
puoi farlo lato client inviando ad entrambi e solo reagendo al 2 ° arrivo sullo stesso cliente ... – dandavis