Socket.io - как передавать сообщения в пространстве имен?
В соответствии с примерами socket.io:
Для трансляции просто добавьте флаг broadcast
в вызовы методов emit
и send
. Вещание означает отправку сообщения всем остальным, кроме сокета, который его запускает.
var io = require('socket.io').listen(80);
io.sockets.on('connection', function (socket) {
socket.broadcast.emit('user connected');
});
Я попытался объединить это с новой функцией socket.io namsepace, поэтому я получил следующее:
var chat = ioserver.of('/chat');
chat.on('connection', function (socket) {
console.log('chat connection');
socket.on('message', function (msg) {
console.log(msg);
chat.send(msg);
});
});
Это прекрасно работает, каждый из каналов чата (и никаких других каналов) получает сообщение. Но отправитель также получает его.
Поэтому я попытался сделать следующее:
chat.on('connection', function (socket) {
console.log('chat connection');
socket.on('message', function (msg) {
console.log(msg);
chat.broadcast.send(msg);
});
});
и получил исключение: "Невозможно вызвать метод" Отправить "из undefined. '
Хорошо, поэтому я подумал, что широковещательная передача - это функция одного сокета (он чувствует себя немного странно - как один сокет может brodacast для всех других...).
Поэтому я попробовал:
chat.on('connection', function (socket) {
console.log('chat connection');
socket.on('message', function (msg) {
console.log(msg);
socket.broadcast.send(msg);
});
});
но теперь это было еще хуже - никто не получил сообщение, даже не отправитель. Во всяком случае, это то, что я логически ожидал - один сокет не может транслировать что-то через себя. И никаких исключений на этот раз, поэтому широковещательная передача определена для сокета.
Если я это сделаю:
chat.on('connection', function (socket) {
console.log('chat connection');
socket.on('message', function (msg) {
console.log(msg);
socket.send(msg);
});
});
тогда только исходный отправитель получает сообщение, и это снова довольно логично - я использовал "отправку" связанного с клиентом сокета.
Итак, вопрос: какой правильный способ использовать функцию широковещания?
Возможно, разработчик socket.io сделал ошибку и добавил функцию широковещания к неправильному объекту (как я понимаю, это должна быть функция пространства имен, но теперь она определена только для сокета)?
Ответы
Ответ 1
Кажется, я смог решить это для себя после открытия щедрости. Извините.
В любом случае, посмотрите, поможет ли это:
chat.on('connection', function (socket) {
socket.on('message', function (msg) {
socket.emit(msg); // Send message to sender
socket.broadcast.emit(msg); // Send message to everyone BUT sender
});
});
Однако вы можете сэкономить некоторую полосу пропускания и создать более быстрый опыт для пользователей, если вы не отправите его отправителю. Просто добавьте их сообщения непосредственно в журнал чата и, возможно, используйте использование только self-emit, чтобы подтвердить, что оно было получено без проблем.
Ответ 2
Ваше решение работает, если вы работаете в среде с событиями, где сообщения от клиента вызывают ответ на все остальные, но не если вы хотите, чтобы сервер отправлял сообщения всем клиентам.
Вы можете сделать это, используя io.sockets.emit
:
var io = require('socket.io').listen(80);
io.sockets.emit('message', { message: "Hello everyone!" });
Однако в документации не ясно, как это сделать для определенного пространства имен. io.sockets
- это просто ярлык для io.of('')
, поэтому вы можете транслировать все в пространстве имен, вызывая io.of('/namespace').emit
:
var io = require('socket.io').listen(80);
io.of('/admins').emit('message', { message: "Hello admins!" });
Ответ 3
var customNS = ioserver.of('/chat');
customNS.on('connection', function (socket) {
socket.on('message', function (msg) {
// Send message to sender
socket.emit(msg);
// Send message to everyone on customNS INCLUDING sender
customNS.emit(msg);
// Send message to everyone on customNS BUT sender
socket.broadcast.emit(msg);
// Send message to everyone on ROOM chanel of customNS INCLUDING sender
customNS.in('ROOM').emit(msg);
// Send message to everyone on ROOM chanel of customNS BUT sender
socket.broadcast.in('ROOM').emit(msg);
});
});
также проверьте этот ответ Отправить ответ всем клиентам, кроме отправителя (Socket.io)
Ответ 4
Возможно, это поможет кому-то
socket.broadcast.to('room1').emit('updatechat', 'SERVER', username + ' has connected to this room');
см.
Учебное пособие по многоязычному чату Nodejs и Socketio