@@ -17,10 +17,39 @@ const METADATA_ARRAY_FIELDS = ["group_members", "support_commands"];
1717interface 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
2251export 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