enum TSessionState {
Normal, // 正常通訊
NoReply, // 標記待關閉(逾時/異常)
Closing, // Shutdown 執行中
Closed // Close 完成,待移除
}
enum TDisconnectType {
Normal, Timeout, Exception, ServerShutdown
}
private void CheckClientState(object state) {
while (!_stopReceiver) {
DateTime now = DateTime.Now;
// 1. 建立副本,避免長時間持有鎖
Hashtable snapshot;
lock (_sessionTable) {
snapshot = new Hashtable(_sessionTable);
}
foreach (TSession session in snapshot.Values) {
Monitor.Enter(session);
try {
switch (session.State) {
case TSessionState.NoReply:
// 階段 1:Shutdown 觸發 EndReceive 完成
session.State = TSessionState.Closing;
session.ClientSocket?.Shutdown(SocketShutdown.Both);
break;
case TSessionState.Closing:
// 階段 2:Close 釋放控制代碼
session.State = TSessionState.Closed;
session.ClientSocket?.Close();
break;
case TSessionState.Closed:
// 階段 3:從表移除,觸發事件
lock (_sessionTable) {
_sessionTable.Remove(session.ID);
Interlocked.Decrement(ref _clientCount);
}
OnClientChanged();
session.ClearBuffer();
break;
case TSessionState.Normal:
// 逾時檢測
if ((now - session.LastActivity).TotalSeconds > _maxIdleSeconds) {
session.DisconnectType = TDisconnectType.Timeout;
session.State = TSessionState.NoReply;
}
break;
}
} finally {
Monitor.Exit(session);
}
}
Thread.Sleep(_scanIntervalMs); // 降低 CPU 佔用
}
}
| 決策 | 理由 |
|---|---|
| 快照副本 | 避免在遍歷時長時間持有 _sessionTable 鎖,減少爭用 |
| Monitor.Enter(session) | 細粒度鎖,單會話操作序列化 |
| 三階段狀態機 | Shutdown→Close→Remove 確保非同步完成回呼安全執行 |
| Interlocked 計數 | 無鎖原子更新連線計數 |
| 逾時驅動狀態轉換 | 被動清理,避免輪詢每個連線發送心跳 |
接收服務僅為核心子系統,完整省級公路交通流量資料中心包含:
總程式碼 60K+ 行,接收服務核心 3K+ 行。
帶詳細註釋的完整原始碼:下載連結(原文連結已失效,此為示意)
本框架展示了 多執行緒 + 非同步 Socket + 狀態機驅動清理 的經典高效能伺服器模式。雖然技術棧已演進,但核心設計思想——細粒度鎖、快照隔離、狀態機資源管理、被動逾時清理——在現代高併發系統設計中依然具有指導意義。