Skip to content

Commit 4d3de26

Browse files
committed
Update client event handling in session
1 parent f10b154 commit 4d3de26

File tree

2 files changed

+52
-22
lines changed

2 files changed

+52
-22
lines changed

server.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,9 @@ async function main() {
118118
logger.log("Stop command received, stopping audio playback.");
119119
}
120120
});
121+
session.on("player-state", (state) => {
122+
logger.log("Player state updated:", state);
123+
});
121124
session.sendMetadata({
122125
title: "Sample Audio",
123126
artist: "Someone on the internet",

src/server/server-session.ts

Lines changed: 49 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,39 @@ const METADATA_ARRAY_FIELDS = ["group_members", "support_commands"];
1717
interface ServerSessionEvents {
1818
"session-end": ServerSession;
1919
"stream-command": ServerClientEvents["stream-command"];
20+
"player-state": {
21+
client: ServerClient;
22+
state: ServerClientEvents["player-state"];
23+
};
24+
}
25+
26+
class ClientEventWrapper {
27+
constructor(
28+
private readonly session: ServerSession,
29+
private readonly client: ServerClient,
30+
) {
31+
this.client.on("stream-command", this._onStreamCommand);
32+
this.client.on("player-state", this._onPlayerState);
33+
}
34+
35+
public tearDown() {
36+
this.client.off("stream-command", this._onStreamCommand);
37+
this.client.off("player-state", this._onPlayerState);
38+
}
39+
40+
private _onStreamCommand = (
41+
command: ServerClientEvents["stream-command"],
42+
) => {
43+
this.session.fire("stream-command", command);
44+
};
45+
46+
private _onPlayerState = (state: ServerClientEvents["player-state"]) => {
47+
this.session.fire("player-state", { client: this.client, state });
48+
};
2049
}
2150

2251
export class ServerSession extends EventEmitter<ServerSessionEvents> {
23-
sessionActive: Set<string> = new Set();
52+
sessionActive: Map<string, ClientEventWrapper> = new Map();
2453

2554
private _lastReportedMetadata: Metadata | null = null;
2655
private _lastReportedArt: Buffer<ArrayBuffer> | null = null;
@@ -31,9 +60,9 @@ export class ServerSession extends EventEmitter<ServerSessionEvents> {
3160
private readonly logger: Logger,
3261
) {
3362
super();
34-
this.group.on("client-removed", this._clientRemoved);
63+
this.group.on("client-removed", this._handleGroupRemovedClient);
3564
this.on("session-end", () => {
36-
this.group.off("client-removed", this._clientRemoved);
65+
this.group.off("client-removed", this._handleGroupRemovedClient);
3766
});
3867
}
3968

@@ -87,7 +116,7 @@ export class ServerSession extends EventEmitter<ServerSessionEvents> {
87116
};
88117
// Send session end message to all active clients
89118
// Avoid sendMessage as it can activate clients
90-
for (const clientId of this.sessionActive) {
119+
for (const clientId of this.sessionActive.keys()) {
91120
const client = this.group.clients.get(clientId);
92121
if (client && client.isReady()) {
93122
client.send(sessionEndMessage);
@@ -114,6 +143,7 @@ export class ServerSession extends EventEmitter<ServerSessionEvents> {
114143
if (!client.isReady()) {
115144
this.logger.log(`Client ${client.clientId} not ready, skipping`);
116145
if (this.sessionActive.has(client.clientId)) {
146+
this.sessionActive.get(client.clientId)!.tearDown();
117147
this.sessionActive.delete(client.clientId);
118148
}
119149
continue;
@@ -135,15 +165,10 @@ export class ServerSession extends EventEmitter<ServerSessionEvents> {
135165
if (this._lastReportedArt) {
136166
client.sendBinary(this._lastReportedArt);
137167
}
138-
client.on("stream-command", (command) => {
139-
this.fire("stream-command", command);
140-
});
141-
// TODO Commented out because we don't unlisten yet and we should pass client along
142-
// client.on("player-state", (state) => {
143-
// console.log(`Unhandled player state from ${client.clientId}:`, state);
144-
// });
145-
146-
this.sessionActive.add(client.clientId);
168+
this.sessionActive.set(
169+
client.clientId,
170+
new ClientEventWrapper(this, client),
171+
);
147172
yield client;
148173
}
149174
}
@@ -251,15 +276,17 @@ export class ServerSession extends EventEmitter<ServerSessionEvents> {
251276
);
252277
}
253278

254-
private _clientRemoved = (client: ServerClient) => {
255-
if (this.sessionActive.has(client.clientId) && client.isReady()) {
256-
client.send({
257-
type: "session/end" as const,
258-
payload: {
259-
sessionId: this.sessionInfo.session_id,
260-
},
261-
});
262-
this.sessionActive.delete(client.clientId);
279+
private _handleGroupRemovedClient = (client: ServerClient) => {
280+
if (!this.sessionActive.has(client.clientId) || !client.isReady()) {
281+
return;
263282
}
283+
this.sessionActive.get(client.clientId)!.tearDown();
284+
this.sessionActive.delete(client.clientId);
285+
client.send({
286+
type: "session/end" as const,
287+
payload: {
288+
sessionId: this.sessionInfo.session_id,
289+
},
290+
});
264291
};
265292
}

0 commit comments

Comments
 (0)