11using System . Net . WebSockets ;
22using System . Text ;
3- using Microsoft . Extensions . Logging ;
3+ using HuaJiBot . NET . Logger ;
44using Newtonsoft . Json . Linq ;
55using WatsonWebsocket ;
6- using ILogger = Microsoft . Extensions . Logging . ILogger ;
76
87namespace HuaJiBot . NET . Websocket ;
98
@@ -16,9 +15,7 @@ public class WebsocketClient : IWebsocketClient
1615 private readonly Uri _url ;
1716 private readonly Dictionary < string , string > _headers ;
1817 private readonly SemaphoreSlim _reconnectLock = new ( 1 , 1 ) ;
19- private bool _isReconnecting ;
20- private int _reconnectAttempts ;
21- private bool _shouldReconnect = true ; // 控制是否应该重连
18+ private int _connectAttempts ;
2219 private Task ? _healthCheckTask ; // 健康检查任务
2320 private const int MaxReconnectDelay = 30000 ; // 最大重连延迟 30 秒
2421 private const int InitialReconnectDelay = 1000 ; // 初始重连延迟 1 秒
@@ -63,7 +60,7 @@ public WebsocketClient(
6360 }
6461 catch ( Exception ex )
6562 {
66- _logger ? . LogWarning ( ex , $ "Failed to set header { header . Key } ") ;
63+ _logger ? . LogError ( ex , $ "Failed to set header { header . Key } ") ;
6764 }
6865 }
6966 } ) ;
@@ -84,12 +81,12 @@ private async Task StartConnectionAsync()
8481 {
8582 try
8683 {
87- _logger ? . LogInformation ( $ "WebSocket connecting to { _url } ") ;
84+ _logger ? . Log ( $ "WebSocket connecting to { _url } ") ;
8885
8986 await Task . Run ( ( ) => _client . Start ( ) , _cancellationTokenSource . Token ) ;
9087
9188 // 重置重连计数
92- _reconnectAttempts = 0 ;
89+ _connectAttempts = 0 ;
9390 }
9491 catch ( Exception e )
9592 {
@@ -102,15 +99,15 @@ private async Task StartConnectionAsync()
10299 Exception = e ,
103100 }
104101 ) ;
105-
106- // 启动自动重连
107- _ = TryReconnectAsync ( ) ;
108102 }
109103 }
110104
111105 private void OnServerConnected ( object ? sender , EventArgs e )
112106 {
113- _logger ? . LogInformation ( "WebSocket connected" ) ;
107+ _logger ? . Log ( "WebSocket connected" ) ;
108+
109+ // 重置重连计数
110+ _connectAttempts = 0 ;
114111
115112 var connectionInfo = new ConnectionInfo
116113 {
@@ -124,7 +121,7 @@ private void OnServerConnected(object? sender, EventArgs e)
124121
125122 private void OnServerDisconnected ( object ? sender , EventArgs e )
126123 {
127- _logger ? . LogInformation ( "WebSocket disconnected" ) ;
124+ _logger ? . Log ( "WebSocket disconnected" ) ;
128125
129126 OnClosed ? . Invoke (
130127 new DisconnectionInfo
@@ -134,107 +131,31 @@ private void OnServerDisconnected(object? sender, EventArgs e)
134131 Timestamp = DateTimeOffset . Now ,
135132 }
136133 ) ;
137-
138- // 只要 _shouldReconnect 为 true,就启动自动重连
139- if ( _shouldReconnect && ! _disposed )
140- {
141- _ = TryReconnectAsync ( ) ;
142- }
143134 }
144135
145- private async Task TryReconnectAsync ( )
136+ public async ValueTask ConnectAsync ( )
146137 {
147- if ( _disposed || ! _shouldReconnect )
148- return ;
149-
138+ _logger ? . LogDebug ( nameof ( ConnectAsync ) + _url ) ;
150139 // 使用信号量防止并发重连
151- if ( ! await _reconnectLock . WaitAsync ( 0 ) )
152- return ;
153-
154- try
140+ if ( await _reconnectLock . WaitAsync ( 0 ) )
155141 {
156- if ( _isReconnecting )
157- return ;
158-
159- _isReconnecting = true ;
160-
161- while ( ! _disposed && _shouldReconnect )
142+ try
162143 {
163- _reconnectAttempts ++ ;
164-
165- // 计算延迟时间(简化的指数退避,1秒到30秒)
166- var delay = Math . Min (
167- InitialReconnectDelay << Math . Min ( _reconnectAttempts - 1 , 5 ) ,
168- MaxReconnectDelay
169- ) ;
170-
171- _logger ? . LogInformation (
172- $ "Attempting to reconnect (attempt { _reconnectAttempts } ) in { delay } ms..."
173- ) ;
174-
175- try
176- {
177- await Task . Delay ( delay , _cancellationTokenSource . Token ) ;
178- }
179- catch ( OperationCanceledException )
180- {
181- // 如果被取消但仍需要重连,继续尝试
182- if ( _shouldReconnect && ! _disposed )
183- {
184- _logger ? . LogInformation (
185- "Reconnect delay cancelled, but will continue trying..."
186- ) ;
187- await Task . Delay ( delay ) ; // 使用不带取消令牌的版本
188- }
189- else
190- {
191- break ;
192- }
193- }
194-
195- try
196- {
197- if ( _client . Connected )
198- {
199- _logger ? . LogInformation ( "Already connected, stopping reconnect attempts" ) ;
200- break ;
201- }
202-
203- _logger ? . LogInformation ( $ "Reconnecting to { _url } ...") ;
204-
205- // 尝试停止现有连接(如果有)
206- if ( _client . Connected )
207- {
208- try
209- {
210- _client . Stop ( ) ;
211- }
212- catch ( Exception stopEx )
213- {
214- _logger ? . LogDebug ( stopEx , "Error stopping client before reconnect" ) ;
215- }
216- }
217-
218- await Task . Run ( ( ) => _client . Start ( ) ) ;
219-
220- _logger ? . LogInformation ( "Reconnected successfully" ) ;
221- _reconnectAttempts = 0 ;
222- break ;
223- }
224- catch ( Exception ex )
144+ _connectAttempts ++ ;
145+ _logger ? . Log ( "Reconnected successfully" ) ;
146+ if ( await _client . StartWithTimeoutAsync ( 10 ) )
225147 {
226- _logger ? . LogWarning ( ex , $ "Reconnect attempt { _reconnectAttempts } failed" ) ;
148+ _connectAttempts = 0 ;
227149 }
228150 }
229- }
230- catch ( Exception ex )
231- {
232- _logger ? . LogError ( ex , "Error during reconnection process" ) ;
233- }
234- finally
235- {
236- _isReconnecting = false ;
237- _reconnectLock . Release ( ) ;
151+ catch ( Exception ex )
152+ {
153+ _logger ? . LogError ( ex , $ "Reconnect attempt { _connectAttempts } failed") ;
154+ }
155+ finally
156+ {
157+ _reconnectLock . Release ( ) ;
158+ }
238159 }
239160 }
240161
@@ -243,36 +164,69 @@ private async Task TryReconnectAsync()
243164 /// </summary>
244165 private async Task RunHealthCheckAsync ( )
245166 {
246- while ( ! _disposed && _shouldReconnect )
167+ while ( ! _disposed )
247168 {
248169 try
249170 {
250- await Task . Delay ( HealthCheckInterval , _cancellationTokenSource . Token ) ;
251- }
252- catch ( OperationCanceledException )
253- {
254- // 如果被取消但仍需要运行健康检查,继续
255- if ( _shouldReconnect && ! _disposed )
171+ // 检查连接状态
172+ if ( ! _client . Connected )
256173 {
257- await Task . Delay ( HealthCheckInterval ) ;
174+ // 计算延迟时间(简化的指数退避,1秒到30秒)
175+ var delay = Math . Min (
176+ InitialReconnectDelay << Math . Min ( _connectAttempts - 1 , 5 ) ,
177+ MaxReconnectDelay
178+ ) ;
179+
180+ _logger ? . Log (
181+ $ "Attempting to reconnect (attempt { _connectAttempts } ) in { delay } ms..."
182+ ) ;
183+ try
184+ {
185+ await Task . Delay ( delay , _cancellationTokenSource . Token ) ;
186+ }
187+ catch ( OperationCanceledException )
188+ {
189+ if ( _disposed )
190+ break ;
191+ }
192+ if ( _disposed )
193+ break ;
194+ await ConnectAsync ( ) ;
258195 }
259196 else
260197 {
261- break ;
262- }
263- }
198+ // 连接正常,重置重连计数
199+ if ( _connectAttempts > 0 )
200+ {
201+ _connectAttempts = 0 ;
202+ }
264203
265- try
266- {
267- // 检查连接状态
268- if ( ! _client . Connected && ! _isReconnecting )
269- {
270- _ = TryReconnectAsync ( ) ;
204+ // 等待下一次健康检查
205+ try
206+ {
207+ await Task . Delay ( HealthCheckInterval , _cancellationTokenSource . Token ) ;
208+ }
209+ catch ( OperationCanceledException )
210+ {
211+ if ( _disposed )
212+ break ;
213+ }
271214 }
272215 }
273216 catch ( Exception ex )
274217 {
275218 _logger ? . LogError ( ex , "Error during health check" ) ;
219+
220+ // 发生错误后等待一段时间再继续
221+ try
222+ {
223+ await Task . Delay ( HealthCheckInterval , _cancellationTokenSource . Token ) ;
224+ }
225+ catch ( OperationCanceledException )
226+ {
227+ if ( _disposed )
228+ break ;
229+ }
276230 }
277231 }
278232
@@ -321,7 +275,7 @@ private async Task SendAsync(string msg)
321275 {
322276 if ( ! _client . Connected )
323277 {
324- _logger ? . LogWarning ( "Cannot send message: WebSocket is not connected" ) ;
278+ _logger ? . Warn ( "Cannot send message: WebSocket is not connected" ) ;
325279 return ;
326280 }
327281
@@ -342,7 +296,6 @@ public void Dispose()
342296 return ;
343297
344298 _disposed = true ;
345- _shouldReconnect = false ; // 停止重连
346299
347300 try
348301 {
@@ -362,7 +315,7 @@ public void Dispose()
362315 }
363316 catch ( Exception ex )
364317 {
365- _logger ? . LogDebug ( ex , "Error waiting for health check task to complete" ) ;
318+ _logger ? . LogError ( ex , "Error waiting for health check task to complete" ) ;
366319 }
367320 }
368321
0 commit comments