專案需遠端即時監控多台無人終端運行狀態,並支援下發控制指令。經過三輪架構重構,最終採用「服務端裝載於控制端、終端為輕量 Client」的雙工通訊模型。本文記錄演進過程與關鍵設計決策。
[ServiceContract(SessionMode=SessionMode.Required, CallbackContract=typeof(IServiceCallback))]
public interface IService {
[OperationContract] void Operation(); // 控制端→終端
[OperationContract] void UpdateStatus(); // 終端→控制端
}
public interface IServiceCallback {
void ReceiveCommand(); void ReceiveStatus();
}
// 服務端用靜態 List 廣播,終端與控制端共用同一服務介面
// 缺點:雙向操作暴露給雙方,安全性差;服務端自我回調邏輯混亂。
// 終端服務
[ServiceContract(CallbackContract=typeof(ITerminalCallback))]
public interface ITerminalService { [OperationContract] void UpdateStatus(); }
public interface ITerminalCallback { void ReceiveCommand(); }
// 控制服務
[ServiceContract(CallbackContract=typeof(IControlCallback))]
public interface IControlService { [OperationContract] void Operation(); }
public interface IControlCallback { void ReceiveStatus(); }
// 兩服務透過靜態 List 交換回調通道
// 缺點:每終端需獨立裝載 TerminalService,單一軟體終端佔用獨立服務實例,資源浪費。
[ServiceContract(SessionMode=SessionMode.Required, CallbackContract=typeof(IServiceCallback))]
public interface IService {
[OperationContract] void Operation(); // 控制端呼叫,實際觸發終端事件
}
public interface IServiceCallback { void ReceiveStatus(); } // 僅控制端實作
public static class Global {
public static List Callbacks = new List();
public static ReceiveCommandHandler ReceiveCommand; // 終端註冊的事件
}
[ServiceBehavior]
public class Service : IService, IDisposable {
IServiceCallback _cb;
public Service() {
_cb = OperationContext.Current.GetCallbackChannel();
Global.Callbacks.Add(_cb);
}
public void Operation() { // 控制端呼叫
if (Global.ReceiveCommand != null) Global.ReceiveCommand();
}
public void Dispose() { Global.Callbacks.Remove(_cb); }
}
// 終端側輕量封裝
public delegate void ReceiveCommandHandler();
public class ServiceHost {
public event ReceiveCommandHandler ReceiveCommand {
add { Global.ReceiveCommand += value; }
remove { Global.ReceiveCommand -= value; }
}
public void UpdateStatus() { // 終端主動呼叫推送狀態
foreach (var cb in Global.Callbacks) cb.ReceiveStatus();
}
public void Start() { /* 啟動 ServiceHost */ }
public void Stop() { /* 停止 */ }
}
Operation),終端僅透過事件接收指令、呼叫 UpdateStatus 推送狀態。ReceiveCommandHandler 簽名或引入命令模式。NetTcpBinding + SessionMode.Required 確保雙工通道可靠。serviceThrottling 最大並發連線數。ServiceHost 內實作(心跳檢測 + 自動重連)。Security_Module),防範中間人攻擊。此架構已在多專案驗證,穩定支撐百台級終端監控場景。