1- using System . Diagnostics . CodeAnalysis ;
1+ using System . Collections . Concurrent ;
2+ using System . Diagnostics ;
3+ using System . Diagnostics . CodeAnalysis ;
24using System . Net . WebSockets ;
35using System . Reflection ;
46using System . Text ;
@@ -15,7 +17,7 @@ namespace yawaflua.WebSockets.Core;
1517[ SuppressMessage ( "ReSharper" , "AsyncVoidLambda" ) ]
1618public class WebSocketRouter
1719{
18- internal static readonly Dictionary < string , Func < WebSocket , HttpContext , Task > > Routes = new ( ) ;
20+ internal static readonly ConcurrentDictionary < string , Func < WebSocket , HttpContext , Task > > Routes = new ( ) ;
1921 internal static readonly List < IWebSocketClient > Clients = new ( ) ;
2022 private readonly IServiceProvider _serviceProvider ;
2123 private readonly ILogger < WebSocketRouter > _logger ;
@@ -69,6 +71,7 @@ internal void DiscoverHandlers()
6971 parameters [ 1 ] . ParameterType != typeof ( HttpContext ) ||
7072 func . ReturnType != typeof ( Task ) )
7173 {
74+ _logger . LogCritical ( $ "Invalid handler signature in { type . Name } .{ func . Name } ") ;
7275 throw new InvalidOperationException (
7376 $ "Invalid handler signature in { type . Name } .{ func . Name } ") ;
7477 }
@@ -79,15 +82,25 @@ internal void DiscoverHandlers()
7982 typeof ( Func < WebSocket , HttpContext , Task > ) ,
8083 func
8184 ) ;
82- Routes . Add ( parentAttributeTemplate , delegateFunc ) ;
85+ if ( ! Routes . TryAdd ( parentAttributeTemplate , delegateFunc ) )
86+ {
87+ _logger . LogCritical ( $ "Error registered whilest adds new route: { parentAttributeTemplate } ") ;
88+ throw new InvalidOperationException (
89+ $ "Error registered whilest adds new route: { parentAttributeTemplate } ") ;
90+ }
8391 }
8492 else
8593 {
86- Routes . Add ( parentAttributeTemplate , async ( ws , context ) =>
94+ if ( ! Routes . TryAdd ( parentAttributeTemplate , async ( ws , context ) =>
95+ {
96+ var instance = context . RequestServices . GetRequiredService ( type ) ;
97+ await ( Task ) func . Invoke ( instance , new object [ ] { ws , context } ) ! ;
98+ } ) )
8799 {
88- var instance = context . RequestServices . GetRequiredService ( type ) ;
89- await ( Task ) func . Invoke ( instance , new object [ ] { ws , context } ) ! ;
90- } ) ;
100+ _logger . LogCritical ( $ "Error registered whilest adds new route: { parentAttributeTemplate } ") ;
101+ throw new InvalidOperationException (
102+ $ "Error registered whilest adds new route: { parentAttributeTemplate } ") ;
103+ }
91104 }
92105 }
93106 else
@@ -96,21 +109,42 @@ internal void DiscoverHandlers()
96109 {
97110 var attribute =
98111 ( WebSocketAttribute ) method . GetCustomAttributes ( typeof ( WebSocketAttribute ) , false ) . First ( ) ;
112+
113+ var key = parentAttributeTemplate + attribute . Template ;
114+
115+ if ( Routes . ContainsKey ( key ) )
116+ {
117+ Debug . WriteLine ( Routes ) ;
118+ _logger . LogCritical ( $ "Duplicate route error: { key } ") ;
119+ throw new InvalidOperationException (
120+ $ "Duplicate route error: { key } ") ;
121+ }
122+
99123 if ( method . IsStatic )
100124 {
101125 var delegateFunc = ( Func < WebSocket , HttpContext , Task > ) Delegate . CreateDelegate (
102126 typeof ( Func < WebSocket , HttpContext , Task > ) ,
103127 method
104128 ) ;
105- Routes . Add ( parentAttributeTemplate + attribute . Template , delegateFunc ) ;
129+ if ( ! Routes . TryAdd ( key , delegateFunc ) )
130+ {
131+ _logger . LogCritical ( $ "Error registered whilest adds new route: { key } ") ;
132+ throw new InvalidOperationException (
133+ $ "Error registered whilest adds new route: { key } ") ;
134+ }
106135 }
107136 else
108137 {
109- Routes . Add ( parentAttributeTemplate + attribute . Template , async ( ws , context ) =>
138+ if ( ! Routes . TryAdd ( key , async ( ws , context ) =>
139+ {
140+ var instance = context . RequestServices . GetRequiredService ( type ) ;
141+ await ( Task ) method . Invoke ( instance , new object [ ] { ws , context } ) ! ;
142+ } ) )
110143 {
111- var instance = context . RequestServices . GetRequiredService ( type ) ;
112- await ( Task ) method . Invoke ( instance , new object [ ] { ws , context } ) ! ;
113- } ) ;
144+ _logger . LogCritical ( $ "Error registered whilest adds new route: { key } ") ;
145+ throw new InvalidOperationException (
146+ $ "Error registered whilest adds new route: { key } ") ;
147+ }
114148 }
115149 }
116150 }
@@ -127,8 +161,19 @@ internal void DiscoverHandlers()
127161 }
128162 catch ( Exception ex )
129163 {
130- _logger . LogCritical ( message : "Error when parsing attributes from assemblies: " , exception : ex ) ;
164+ _logger . LogCritical ( "Error when parsing attributes from assemblies: {ex}" , ex ) ;
165+ Debug . WriteLine ( ex ) ;
166+ Debug . WriteLine ( Routes ) ;
167+ throw new Exception ( "Error when parsing attributes from assemblies" , ex ) ;
131168 }
169+
170+ #if DEBUG
171+ _logger . LogDebug ( "Routes:" ) ;
172+ foreach ( var route in Routes )
173+ {
174+ _logger . LogDebug ( "Key:FuncName => {k}:{f}" , route . Key , route . Value . Method . Name ) ;
175+ }
176+ #endif
132177 }
133178
134179 internal async Task HandleRequest ( HttpContext context , CancellationToken cts = default )
@@ -179,12 +224,13 @@ await handler(
179224 }
180225 catch ( Exception ex )
181226 {
182- _logger . LogError ( message : "Error with handling request: " , exception : ex ) ;
227+ _logger . LogError ( "Error with handling request: {ex}" , ex ) ;
183228 await Task . Run ( async ( ) =>
184229 {
185230 if ( _webSocketConfig ? . OnErrorHandler != null )
186231 await _webSocketConfig . OnErrorHandler ( ex , new WebSocket ( webSocket , client , webSocketManager ) , context ) ;
187232 } , cts ) ;
233+
188234 }
189235
190236 } , cts ) ;
@@ -197,7 +243,7 @@ await Task.Run(async () =>
197243 }
198244 catch ( Exception ex )
199245 {
200- _logger . LogError ( ex , $ "Error when handle request { context . Connection . Id } : ") ;
246+ _logger . LogError ( $ "Error when handle request { context . Connection . RemoteIpAddress } : { ex } ") ;
201247 if ( _webSocketConfig ! . OnConnectionErrorHandler != null )
202248 await _webSocketConfig . OnConnectionErrorHandler ( ex , context ) ;
203249 }
0 commit comments