@@ -232,11 +232,11 @@ await clusterManager.RegisterConnectionAsync(
232232 context . Request . Path ,
233233 remoteIpAddress ,
234234 remotePort ) ;
235- logger . LogDebug ( $ "Registered connection { context . Connection . Id } with cluster manager" ) ;
235+ logger . LogDebug ( string . Format ( I18nText . WS_INTERACTIVE_TEXT_TEMPALTE , context . Connection . RemoteIpAddress , context . Connection . RemotePort , context . Connection . Id , I18nText . ConnectionEntry_ClusterManagerRegistered ) ) ;
236236 }
237237 catch ( Exception ex )
238238 {
239- logger . LogWarning ( ex , $ "Failed to register connection { context . Connection . Id } with cluster manager" ) ;
239+ logger . LogWarning ( ex , string . Format ( I18nText . WS_INTERACTIVE_TEXT_TEMPALTE , context . Connection . RemoteIpAddress , context . Connection . RemotePort , context . Connection . Id , I18nText . ConnectionEntry_ClusterManagerRegisterFailed ) ) ;
240240 }
241241 }
242242
@@ -255,7 +255,7 @@ await clusterManager.RegisterConnectionAsync(
255255 {
256256 if ( webSocket . CloseStatus == null && webSocket . State == WebSocketState . Open )
257257 {
258- await webSocket . CloseAsync ( WebSocketCloseStatus . PolicyViolation , string . Empty , CancellationToken . None ) . ConfigureAwait ( false ) ;
258+ // await webSocket.CloseAsync(WebSocketCloseStatus.PolicyViolation, string.Empty, CancellationToken.None).ConfigureAwait(false);
259259 webSocket . Abort ( ) ;
260260 }
261261 webSocketCloseStatus = webSocket . CloseStatus ;
@@ -303,11 +303,13 @@ private async Task MvcForward(HttpContext context, WebSocket webSocket, WebSocke
303303 {
304304 string wsCloseDesc = string . Empty ;
305305 using MemoryStream wsReceiveReader = new MemoryStream ( ReceiveTextBufferSize ) ;
306+ bool connectionClosed = false ;
306307 do
307308 {
308309 long requestTime = DateTime . Now . Ticks ;
309310 WebSocketReceiveResult result = null ;
310311 SemaphoreSlim endPointSlim = null ;
312+ bool receivedClose = false ;
311313 try
312314 {
313315 // Connection level restrictions
@@ -320,7 +322,8 @@ private async Task MvcForward(HttpContext context, WebSocket webSocket, WebSocke
320322 {
321323 if ( webSocket . State == WebSocketState . Aborted || webSocket . State == WebSocketState . CloseReceived || webSocket . State == WebSocketState . Closed )
322324 {
323- // exit
325+ // 连接已关闭,设置标志并退出
326+ connectionClosed = true ;
324327 break ;
325328 }
326329 else
@@ -341,14 +344,32 @@ private async Task MvcForward(HttpContext context, WebSocket webSocket, WebSocke
341344
342345 try
343346 {
344- while ( ! messageComplete )
347+ while ( ! messageComplete && ! receivedClose )
345348 {
346349 // 接收数据帧
347350 result = await webSocket . ReceiveAsync ( new ArraySegment < byte > ( buffer ) , CancellationToken . None ) ;
348351
349- // 如果接收到Close消息,直接退出
352+ // 如果接收到Close消息,保存状态并退出接收循环
350353 if ( result . MessageType == WebSocketMessageType . Close )
351354 {
355+ receivedClose = true ;
356+ connectionClosed = true ;
357+ wsCloseDesc = result . CloseStatusDescription ;
358+ // 响应Close帧(如果连接状态允许)
359+ if ( webSocket . State == WebSocketState . Open || webSocket . State == WebSocketState . CloseReceived )
360+ {
361+ try
362+ {
363+ await webSocket . CloseAsync (
364+ result . CloseStatus ?? WebSocketCloseStatus . NormalClosure ,
365+ result . CloseStatusDescription ?? string . Empty ,
366+ CancellationToken . None ) ;
367+ }
368+ catch ( Exception ex )
369+ {
370+ logger . LogDebug ( string . Format ( I18nText . WS_INTERACTIVE_TEXT_TEMPALTE , context . Connection . RemoteIpAddress , context . Connection . RemotePort , context . Connection . Id , I18nText . ConnectionEntry_CloseResponseFailed + Environment . NewLine + ex . Message ) ) ;
371+ }
372+ }
352373 break ;
353374 }
354375
@@ -444,26 +465,31 @@ await bandwidthLimitManager.WaitForBandwidthAsync(
444465 // 归还buffer
445466 ArrayPool < byte > . Shared . Return ( buffer ) ;
446467 }
447- // 如果接收到的消息是Close时,断开连接
448- if ( result . MessageType == WebSocketMessageType . Close )
468+
469+ // 如果接收到Close消息,直接退出当前循环,不再处理数据
470+ if ( receivedClose )
449471 {
472+ // 设置连接关闭标志,退出外层循环
473+ connectionClosed = true ;
450474 break ;
451475 }
476+
452477 // 缩小Capacity避免Getbuffer出现0x00
453478 if ( wsReceiveReader . Capacity > wsReceiveReader . Length )
454479 {
455480 wsReceiveReader . Capacity = ( int ) wsReceiveReader . Length ;
456481 }
457482 #endregion
458483
459- // 执行AfterReceivingData管道
460- _ = await InvokePipeline ( RequestPipelineStage . AfterReceivingData , PipelineContext . CreateReceive ( context , webSocket , result , wsReceiveReader . GetBuffer ( ) , webSocketOption ) ) ;
461-
462- if ( result == null )
484+ // 如果result为null或接收到Close消息,跳过后续处理
485+ if ( result == null || receivedClose )
463486 {
464487 continue ;
465488 }
466489
490+ // 执行AfterReceivingData管道
491+ _ = await InvokePipeline ( RequestPipelineStage . AfterReceivingData , PipelineContext . CreateReceive ( context , webSocket , result , wsReceiveReader . GetBuffer ( ) , webSocketOption ) ) ;
492+
467493 // 在接收完数据后,应用端点级别的限速策略
468494 string endpoint = null ;
469495 if ( bandwidthLimitManager != null && wsReceiveReader . Length > 0 )
@@ -578,13 +604,19 @@ await bandwidthLimitManager.WaitForBandwidthAsync(
578604 }
579605 finally
580606 {
581- wsCloseDesc = result ? . CloseStatusDescription ;
607+ // 保存Close状态信息(如果还没有保存)
608+ if ( result != null && ! string . IsNullOrEmpty ( result . CloseStatusDescription ) && string . IsNullOrEmpty ( wsCloseDesc ) )
609+ {
610+ wsCloseDesc = result . CloseStatusDescription ;
611+ }
582612
613+ // 重置接收缓冲区
583614 wsReceiveReader . Flush ( ) ;
584615 wsReceiveReader . SetLength ( 0 ) ;
585616 wsReceiveReader . Seek ( 0 , SeekOrigin . Begin ) ;
586617 wsReceiveReader . Position = 0 ;
587618
619+ // 释放信号量
588620 if ( ParallelForwardLimitSlim != null )
589621 {
590622 ParallelForwardLimitSlim . Release ( ) ;
@@ -595,15 +627,34 @@ await bandwidthLimitManager.WaitForBandwidthAsync(
595627 }
596628 }
597629
598- } while ( ! appLifetime . ApplicationStopping . IsCancellationRequested ) ;
630+ } while ( ! appLifetime . ApplicationStopping . IsCancellationRequested && ! connectionClosed ) ;
631+
632+ // 连接断开处理
633+ // 如果连接仍然打开,需要关闭它
634+ if ( webSocket . State == WebSocketState . Open || webSocket . State == WebSocketState . CloseReceived )
635+ {
636+ try
637+ {
638+ // 如果已经收到了Close消息,使用接收到的Close状态
639+ // 否则使用默认的关闭状态
640+ WebSocketCloseStatus closeStatus = webSocket . CloseStatus ??
641+ ( webSocket . State == WebSocketState . Aborted ?
642+ WebSocketCloseStatus . InternalServerError :
643+ WebSocketCloseStatus . NormalClosure ) ;
599644
600- // 连接断开
601- if ( webSocket . State == WebSocketState . Open || webSocket . State == WebSocketState . CloseSent )
645+ string closeDescription = wsCloseDesc ?? string . Empty ;
646+
647+ await webSocket . CloseAsync ( closeStatus , closeDescription , CancellationToken . None ) ;
648+ }
649+ catch ( Exception ex )
650+ {
651+ logger . LogDebug ( string . Format ( I18nText . WS_INTERACTIVE_TEXT_TEMPALTE , context . Connection . RemoteIpAddress , context . Connection . RemotePort , context . Connection . Id , I18nText . ConnectionEntry_CloseConnectionError + Environment . NewLine + ex . Message ) ) ;
652+ }
653+ }
654+ // 如果已经发送了Close消息,等待对方关闭
655+ else if ( webSocket . State == WebSocketState . CloseSent )
602656 {
603- await webSocket . CloseAsync ( webSocket . CloseStatus == null ?
604- webSocket . State == WebSocketState . Aborted ?
605- WebSocketCloseStatus . InternalServerError : WebSocketCloseStatus . NormalClosure
606- : webSocket . CloseStatus . Value , wsCloseDesc , CancellationToken . None ) ;
657+ // 连接正在关闭中,不需要额外操作
607658 }
608659 }
609660 catch ( Exception ex )
@@ -948,7 +999,7 @@ public static async Task<MvcResponseScheme> MvcDistributeAsync(WebSocketRouteOpt
948999 catch ( FormatException ex )
9491000 {
9501001 // ConvertTo 抛出 类型转换失败
951- logger . LogTrace ( string . Format ( I18nText . WS_INTERACTIVE_TEXT_TEMPALTE , context . Connection . RemoteIpAddress , context . Connection . RemotePort , context . Connection . Id , $ " { requestPath } . { item . Name } " + I18nText . MvcForwardSendData_RequestBodyParameterFormatError + ex . Message + Environment . NewLine + ex . StackTrace ) ) ;
1002+ logger . LogTrace ( string . Format ( I18nText . WS_INTERACTIVE_TEXT_TEMPALTE , context . Connection . RemoteIpAddress , context . Connection . RemotePort , context . Connection . Id , string . Concat ( requestPath , "." , item . Name , I18nText . MvcForwardSendData_RequestBodyParameterFormatError , ex . Message , Environment . NewLine , ex . StackTrace ) ) ) ;
9521003 }
9531004 args [ i ] = parmVal ;
9541005 }
@@ -1121,7 +1172,7 @@ private async Task MvcChannel_OnDisconnected(HttpContext context, WebSocketClose
11211172 msg = I18nText . WebSocketCloseStatus_ConnectionShutdown ;
11221173 }
11231174
1124- logger . LogInformation ( string . Format ( I18nText . WS_INTERACTIVE_TEXT_TEMPALTE , context . Connection . RemoteIpAddress , context . Connection . RemotePort , context . Connection . Id , I18nText . OnDisconnected_Disconnected + msg + Environment . NewLine + $ "Status:{ webSocketCloseStatus . ToString ( ) ?? "NoHandshakeSucceeded" } " ) ) ;
1175+ logger . LogInformation ( string . Format ( I18nText . WS_INTERACTIVE_TEXT_TEMPALTE , context . Connection . RemoteIpAddress , context . Connection . RemotePort , context . Connection . Id , string . Concat ( I18nText . OnDisconnected_Disconnected , msg , Environment . NewLine , "Status:" , webSocketCloseStatus ? . ToString ( ) ?? "NoHandshakeSucceeded" ) ) ) ;
11251176
11261177 try
11271178 {
@@ -1148,11 +1199,11 @@ private async Task MvcChannel_OnDisconnected(HttpContext context, WebSocketClose
11481199 try
11491200 {
11501201 await clusterManager . UnregisterConnectionAsync ( context . Connection . Id ) ;
1151- logger . LogDebug ( $ "Unregistered connection { context . Connection . Id } from cluster manager" ) ;
1202+ logger . LogDebug ( string . Format ( I18nText . WS_INTERACTIVE_TEXT_TEMPALTE , context . Connection . RemoteIpAddress , context . Connection . RemotePort , context . Connection . Id , I18nText . ConnectionEntry_ClusterManagerUnregistered ) ) ;
11521203 }
11531204 catch ( Exception ex )
11541205 {
1155- logger . LogWarning ( ex , $ "Failed to unregister connection { context . Connection . Id } from cluster manager" ) ;
1206+ logger . LogWarning ( ex , string . Format ( I18nText . WS_INTERACTIVE_TEXT_TEMPALTE , context . Connection . RemoteIpAddress , context . Connection . RemotePort , context . Connection . Id , I18nText . ConnectionEntry_ClusterManagerUnregisterFailed ) ) ;
11561207 }
11571208 }
11581209 }
@@ -1193,22 +1244,22 @@ public virtual async Task<bool> MvcChannel_OnBeforeConnection(HttpContext contex
11931244 case AccessDeniedAction . ReturnForbidden :
11941245 context . Response . StatusCode = 403 ;
11951246 await context . Response . WriteAsync ( policy . DenialMessage ?? "Access denied" ) ;
1196- logger . LogWarning ( $ "Access denied for IP { ipAddress } from { context . Request . Path } : { policy . DenialMessage } " ) ;
1247+ logger . LogWarning ( string . Format ( I18nText . ConnectionEntry_AccessDeniedWithMessage , ipAddress , context . Request . Path , policy . DenialMessage ?? string . Empty ) ) ;
11971248 break ;
11981249 case AccessDeniedAction . ReturnUnauthorized :
11991250 context . Response . StatusCode = 401 ;
12001251 await context . Response . WriteAsync ( policy . DenialMessage ?? "Unauthorized" ) ;
1201- logger . LogWarning ( $ "Access denied for IP { ipAddress } from { context . Request . Path } : { policy . DenialMessage } " ) ;
1252+ logger . LogWarning ( string . Format ( I18nText . ConnectionEntry_AccessDeniedWithMessage , ipAddress , context . Request . Path , policy . DenialMessage ?? string . Empty ) ) ;
12021253 break ;
12031254 case AccessDeniedAction . CloseConnection :
12041255 default :
1205- logger . LogWarning ( $ "Access denied for IP { ipAddress } from { context . Request . Path } : { policy . DenialMessage } " ) ;
1256+ logger . LogWarning ( string . Format ( I18nText . ConnectionEntry_AccessDeniedWithMessage , ipAddress , context . Request . Path , policy . DenialMessage ?? string . Empty ) ) ;
12061257 break ;
12071258 }
12081259 }
12091260 else
12101261 {
1211- logger . LogWarning ( $ "Access denied for IP { ipAddress } from { context . Request . Path } " ) ;
1262+ logger . LogWarning ( string . Format ( I18nText . ConnectionEntry_AccessDenied , ipAddress , context . Request . Path ) ) ;
12121263 }
12131264
12141265 return false ;
@@ -1217,7 +1268,7 @@ public virtual async Task<bool> MvcChannel_OnBeforeConnection(HttpContext contex
12171268 }
12181269 catch ( Exception ex )
12191270 {
1220- logger . LogError ( ex , "Error checking access control" ) ;
1271+ logger . LogError ( ex , I18nText . ConnectionEntry_AccessControlError ) ;
12211272 // Allow connection on error to avoid blocking legitimate users / 出错时允许连接,避免阻止合法用户
12221273 }
12231274 }
0 commit comments