Percebi esse comportamento estranho durante a transmissão para outros clientes usando socket.broadcast.emit()
Aqui está o código de amostra do problema:
...notifyOtherClients = function(room, e, data, socket)
{
// sending to all clients in a room except sender
var transport = socket.broadcast.to(room);
//
setTimeout(function(){
// #method1: this works as expected: all clients receive event except the sender
socket.broadcast.to(room).emit(e, data);
// #method2: this doesn't work though: all clients receive this event. Why?! Bug?
transport.emit(e, data);
// logs out 'true'
console.log(transport === socket.broadcast.to(room));
},
1000);
};
...
notifyOtherClients("myRoom", "someEvent", { }, socket);
O que estou perdendo aqui? Por que # method2 não funciona conforme o esperado.
Obrigado.
O que retorna de socket.broadcast.to(room)
?
@ Mad-Head De acordo com a documentação, retorna a mesma instância de soquete quase como todos os outros métodos para manter a capacidade de encadeamento.
http://socket.io/docs/server-api/#socket #to (room: string): socket
O engraçado é que isso rastreia a verdade
console.log(transport === socket.broadcast.to(room));
Oi! socket.broadcast
na verdade adiciona um sinalizador temporário (a saber, broadcast
) que será usado na próxima vez que emit
for chamado no socket
.
O sinalizador é usado pela primeira vez e, em seguida, excluído, daí o resultado de sua segunda chamada.
Olá! Hm ... talvez eu não tenha sido claro o suficiente. Deixe-me tornar mais óbvio:
amostra1
setTimeout(function(){
// #method1: this works as expected: all clients receive event except the sender
socket.broadcast.to(room).emit(e, data);
},
1000);
amostra2
var transport = socket.broadcast.to(room);
setTimeout(function(){
// #method2: this doesn't work though: all clients receive this event. Why?! Bug?
transport.emit(e, data);
},
1000);
Portanto, não está relacionado à bandeira. Os dois exemplos acima devem funcionar da mesma forma, mas não funcionam. Esse é o problema e eu tenho batido contra a parede por meio dia para descobrir o porquê.
UPD: na verdade @darrachequesne você está certo. Eu olhei a fonte: toda vez que emit () é chamado de _rooms get flushed e o problema estranho ocorreu enquanto o setTimeout ainda estava em andamento, outro método chamado emit () limpava a sala (ping era o problema)
Foi o que aconteceu
1. setup a room with to()
2. start timeout for 1000 ms
...
[some where between 0 and 1000 ms] ping occurs i.e. emit() and flushes the room
...
3. timeout calls socket but the room's already flushed.
4. *problemo* all clients get notified including the sender socket.
Muito obrigado pela sua sugestão @darrachequesne.
Fechando este
Comentários muito úteis
Oi!
socket.broadcast
na verdade adiciona um sinalizador temporário (a saber,broadcast
) que será usado na próxima vez queemit
for chamado nosocket
.O sinalizador é usado pela primeira vez e, em seguida, excluído, daí o resultado de sua segunda chamada.