Я заметил это странное поведение при трансляции другим клиентам с использованием socket.broadcast.emit()
Вот пример кода проблемы:
...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);
Что мне здесь не хватает? Почему # method2 не работает должным образом.
Спасибо.
Что дает socket.broadcast.to(room)
?
@ Mad-Head Согласно документации, возвращает тот же экземпляр сокета, почти как и все другие методы, чтобы сохранить цепочку.
http://socket.io/docs/server-api/#socket #to (комната: строка): сокет
Самое смешное, что это правда
console.log(transport === socket.broadcast.to(room));
Привет! socket.broadcast
фактически добавляет временный флаг (а именно, broadcast
), который будет использоваться при следующем вызове emit
для socket
.
Флаг используется в первый раз, а затем удаляется, отсюда и результат вашего второго вызова.
Всем привет! Хм ... может я не достаточно ясно понял. Позвольте мне сделать это более очевидным:
sample1
setTimeout(function(){
// #method1: this works as expected: all clients receive event except the sender
socket.broadcast.to(room).emit(e, data);
},
1000);
sample2
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);
Так что это не связано с флагом. Два приведенных выше примера должны работать одинаково, но это не так. Вот в чем проблема, и я бился об стену примерно полдня, чтобы понять, почему.
UPD: вообще-то @darrachequesne вы правы. Я заглянул в источник: каждый раз, когда emit () вызывается _rooms get flisted, и возникла странная проблема, поскольку пока setTimeout все еще выполнялся, другой метод, называемый emit (), сбрасывал комнату (проблема была ping)
вот что случилось
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.
Большое спасибо за ваше предложение @darrachequesne.
Закрытие этого
Самый полезный комментарий
Привет!
socket.broadcast
фактически добавляет временный флаг (а именно,broadcast
), который будет использоваться при следующем вызовеemit
дляsocket
.Флаг используется в первый раз, а затем удаляется, отсюда и результат вашего второго вызова.