feat: add room events

The adapter will now emit the following events:

- create-room (arg: room)
- delete-room (arg: room)
- join-room (args: room, sid)
- leave-room (args: room, sid)

Related: https://github.com/socketio/socket.io/issues/2897
This commit is contained in:
Damien Arrachequesne
2021-01-15 01:22:49 +01:00
parent 313c5a9fb6
commit 155fa6333a
2 changed files with 102 additions and 7 deletions

View File

@@ -59,8 +59,12 @@ export class Adapter extends EventEmitter {
if (!this.rooms.has(room)) {
this.rooms.set(room, new Set());
this.emit("create-room", room);
}
if (!this.rooms.get(room).has(id)) {
this.rooms.get(room).add(id);
this.emit("join-room", room, id);
}
this.rooms.get(room).add(id);
}
}
@@ -75,9 +79,19 @@ export class Adapter extends EventEmitter {
this.sids.get(id).delete(room);
}
this._del(room, id);
}
private _del(room, id) {
if (this.rooms.has(room)) {
this.rooms.get(room).delete(id);
if (this.rooms.get(room).size === 0) this.rooms.delete(room);
const deleted = this.rooms.get(room).delete(id);
if (deleted) {
this.emit("leave-room", room, id);
}
if (this.rooms.get(room).size === 0) {
this.rooms.delete(room);
this.emit("delete-room", room);
}
}
}
@@ -92,10 +106,7 @@ export class Adapter extends EventEmitter {
}
for (const room of this.sids.get(id)) {
if (this.rooms.has(room)) {
this.rooms.get(room).delete(id);
if (this.rooms.get(room).size === 0) this.rooms.delete(room);
}
this._del(room, id);
}
this.sids.delete(id);

View File

@@ -57,4 +57,88 @@ describe("socket.io-adapter", () => {
expect(rooms.size).to.be(2);
expect(adapter.socketRooms("s4")).to.be(undefined);
});
describe("events", () => {
it("should emit a 'create-room' event", done => {
const adapter = new Adapter({ server: { encoder: null } });
adapter.on("create-room", room => {
expect(room).to.eql("r1");
done();
});
adapter.addAll("s1", new Set(["r1"]));
});
it("should not emit a 'create-room' event if the room already exists", done => {
const adapter = new Adapter({ server: { encoder: null } });
adapter.addAll("s1", new Set(["r1"]));
adapter.on("create-room", room => {
done(new Error("should not happen"));
});
adapter.addAll("s2", new Set(["r1"]));
done();
});
it("should emit a 'join-room' event", done => {
const adapter = new Adapter({ server: { encoder: null } });
adapter.on("join-room", (room, sid) => {
expect(room).to.eql("r1");
expect(sid).to.eql("s1");
done();
});
adapter.addAll("s1", new Set(["r1"]));
});
it("should not emit a 'join-room' event if the sid is already in the room", done => {
const adapter = new Adapter({ server: { encoder: null } });
adapter.addAll("s1", new Set(["r1", "r2"]));
adapter.on("join-room", () => {
done(new Error("should not happen"));
});
adapter.addAll("s1", new Set(["r1"]));
done();
});
it("should emit a 'leave-room' event with del method", done => {
const adapter = new Adapter({ server: { encoder: null } });
adapter.on("leave-room", (room, sid) => {
expect(room).to.eql("r1");
expect(sid).to.eql("s1");
done();
});
adapter.addAll("s1", new Set(["r1"]));
adapter.del("s1", "r1");
});
it("should emit a 'leave-room' event with delAll method", done => {
const adapter = new Adapter({ server: { encoder: null } });
adapter.on("leave-room", (room, sid) => {
expect(room).to.eql("r1");
expect(sid).to.eql("s1");
done();
});
adapter.addAll("s1", new Set(["r1"]));
adapter.delAll("s1");
});
it("should emit a 'delete-room' event", done => {
const adapter = new Adapter({ server: { encoder: null } });
adapter.on("delete-room", room => {
expect(room).to.eql("r1");
done();
});
adapter.addAll("s1", new Set(["r1"]));
adapter.delAll("s1");
});
it("should not emit a 'delete-room' event if there is another sid in the room", done => {
const adapter = new Adapter({ server: { encoder: null } });
adapter.on("delete-room", room => {
done(new Error("should not happen"));
});
adapter.addAll("s1", new Set(["r1"]));
adapter.addAll("s2", new Set(["r1", "r2"]));
adapter.delAll("s1");
done();
});
});
});