ОК, чтение здесь в документации Socket.IO - это утверждение ...
Чтобы выйти из канала, вы вызываете leave
так же, как join
. Оба метода являются асинхронными и принимают аргумент callback
.
..., что очень важно.
Лучше объяснено здесь .
Таким образом, "соединения" могут быть обещаны, а rusulting обещания агрегированы с Promise.all()
.
io.on('connection', socket => {
console.log('New client connected');
socket.on('fetchConvos', async function(rooms) {
try {
let results = await mapper(rooms); // array
// first, map results to array of Promises, where each Promise represents a socket.join() operation.
let promises = results.map(room => {
// here, promisify socket.join() on-the-fly and return Promise
return new Promise((resolve, reject) => {
socket.join(room, (err) => {
if(err) reject(err);
else resolve(room);
});
});
});
// Here, you probably want any failures of socket.join() not to scupper promise aggregation with Promise.all();
// see https://stackoverflow.com/a/31424853/3478010
const reflect = p => p.then(v => ({v, status: "fulfilled" }),
e => ({e, status: "rejected" }));
let rooms = (await Promise.all(promises.map(reflect))).filter(o => o.status !== 'rejected').map(o => o.v);
let rooms_ = Object.keys(socket.rooms); // from documentation
// rooms and rooms_ should be similar, maybe the same ???
console.log(rooms);
console.log(rooms_);
// now, map rooms, or rooms_, to whatever you wish to emit to `chat`, eg ...
let roomsString = rooms.join(', '); // .join() here is the Array method Array.prototype.join()
socket.emit('chat', `You are now in these rooms: ${roomsString}`); // emit to `chat`
// Based on example in the documentation, you can also broadcast to to everyone in each room joined, eg ...
rooms_.forEach(room => {
io.to(room).emit('a new user has joined the room'); // broadcast
});
}
catch(error) {
console.log(error);
socket.emit('chat', error.message); // for debugging
}
});
socket.on("disconnect", () => {
console.log("Client disconnected");
});
});
В качестве альтернативы socket.join()
также принимает массив комнат, что упрощает задачу:
io.on('connection', socket => {
console.log('New client connected');
socket.on('fetchConvos', async function(rooms) {
try {
let results = await mapper(rooms); // array
// promisifying socket.join() allows `await` to be used (and avoids nesting).
await new Promise((resolve, reject) => {
socket.join(rooms, (err) => {
if(err) reject(err);
else resolve();
});
});
let rooms_ = Object.keys(socket.rooms); // from documentation
// rooms and rooms_ should be similar, maybe the same ???
console.log(rooms);
console.log(rooms_);
// now, from rooms, or rooms_, compose whatever you wish to emit to `chat`, eg ...
let roomsString = rooms.join(', '); // .join() here is the Array method Array.prototype.join()
socket.emit('chat', `You are now in these rooms: ${roomsString}`); // emit to `chat`
// Based on example in the documentation, you can also broadcast to to everyone in each room joined.
rooms.forEach(room => {
io.to(room).emit('a new user has joined the room'); // broadcast
});
}
catch(error) {
console.log(error);
socket.emit('chat', error.message); // for debugging
}
});
socket.on("disconnect", () => {
console.log("Client disconnected");
});
});
Ничего из этого не проверено, и есть некоторые догадки. Будьте готовы сделать некоторую отладку.