@@ -144,6 +144,11 @@ public void modifyHandshake(ServerEndpointConfig sec, HandshakeRequest request,
144144 if (idx != -1 ) {
145145 path = path .substring (0 , idx );
146146 }
147+ // normalize path by removing trailing slashes (e.g., "/live/" -> "/live")
148+ while (path .length () > 1 && path .endsWith ("/" )) {
149+ path = path .substring (0 , path .length () - 1 );
150+ }
151+ log .debug ("Normalized path: {}" , path );
147152 // get the manager
148153 WebSocketPlugin plugin = (WebSocketPlugin ) PluginRegistry .getPlugin (WebSocketPlugin .NAME );
149154 WebSocketScopeManager manager = plugin .getManager (path );
@@ -156,8 +161,12 @@ public void modifyHandshake(ServerEndpointConfig sec, HandshakeRequest request,
156161 if (scope == null ) {
157162 // split up the path into usable scope names
158163 String [] paths = path .split ("\\ /" );
159- // parent scope
160- IScope appScope = Optional .ofNullable (applicationScope ).orElse (plugin .getApplicationScope (path ));
164+ // parent scope - prefer manager's app scope over separate lookup
165+ IScope appScope = Optional .ofNullable (applicationScope ).orElse (manager .getApplication ());
166+ if (appScope == null ) {
167+ // fallback to plugin lookup
168+ appScope = plugin .getApplicationScope (path );
169+ }
161170 IScope parentScope = appScope ;
162171 // room scope
163172 IScope roomScope = null ;
@@ -177,23 +186,37 @@ public void modifyHandshake(ServerEndpointConfig sec, HandshakeRequest request,
177186 parentScope = roomScope ;
178187 }
179188 }
180- // create and add the websocket scope for the new room scope
181- manager .makeScope (roomScope );
182- // get the new ws scope
183- scope = manager .getScope (path );
184- // copy the listeners from the app websocket scope
185- Set <IWebSocketDataListener > listeners = ((WebSocketScope ) appScope .getAttribute (WSConstants .WS_SCOPE )).getListeners ();
186- for (IWebSocketDataListener listener : listeners ) {
187- log .debug ("Adding listener: {}" , listener );
188- scope .addListener (listener );
189+ // create and add the websocket scope for the room or app scope
190+ IScope scopeToUse = roomScope != null ? roomScope : appScope ;
191+ if (scopeToUse != null ) {
192+ manager .makeScope (scopeToUse );
193+ // get the new ws scope
194+ scope = manager .getScope (path );
195+ // copy the listeners from the app websocket scope if available
196+ if (appScope != null && appScope .hasAttribute (WSConstants .WS_SCOPE )) {
197+ WebSocketScope appWsScope = (WebSocketScope ) appScope .getAttribute (WSConstants .WS_SCOPE );
198+ if (appWsScope != null && scope != null ) {
199+ Set <IWebSocketDataListener > listeners = appWsScope .getListeners ();
200+ for (IWebSocketDataListener listener : listeners ) {
201+ log .debug ("Adding listener: {}" , listener );
202+ scope .addListener (listener );
203+ }
204+ }
205+ }
206+ } else {
207+ log .warn ("Cannot create websocket scope - no valid scope available for path: {}" , path );
189208 }
190209 }
191- // add the websocket scope to the user props
192- sec .getUserProperties ().put (WSConstants .WS_SCOPE , scope );
193- // run through any modifiers
194- handshakeModifiers .forEach (modifier -> {
195- modifier .modifyHandshake (request , response );
196- });
210+ // add the websocket scope to the user props if available
211+ if (scope != null ) {
212+ sec .getUserProperties ().put (WSConstants .WS_SCOPE , scope );
213+ // run through any modifiers
214+ handshakeModifiers .forEach (modifier -> {
215+ modifier .modifyHandshake (request , response );
216+ });
217+ } else {
218+ log .warn ("WebSocket scope is null for path: {} - handshake may fail" , path );
219+ }
197220 } else {
198221 log .warn ("No websocket manager found for path: {} requested uri: {}" , path , request .getRequestURI ().toString ());
199222 }
0 commit comments