using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.ComponentModel; using System.Linq; using System.Text; using System.Threading.Tasks; using Fleck; namespace DB { /// <summary> /// 客戶端網絡狀態 /// </summary> /// public enum NetStateEnum { [Description("已鏈接")] Connected = 1, [Description("已發送")] SendData = 2, [Description("已接收")] ReceiveData = 3, [Description("已解析")] ParseData = 4, [Description("已離線")] Disconnected = 5, [Description("上報超時")] ReportTimeout = 6 } /// <summary> /// 記錄每個Socket鏈接 /// </summary> public class SocketConnectionInfo { private const int SocketDataBufferSize = 1024;//若是單包數據字節數大於該值則須要加大此值,以避免分包 /// <summary> /// 構造函數將一個套接字和一個客戶號碼 /// </summary> /// <param name="socket">套接字</param> /// <param name="connectionId">設備惟一號</param> internal SocketConnectionInfo(IWebSocketConnection socket, string connectionId) { ConnectionId = connectionId; CurrentSocket = socket; DataBuffer = new byte[SocketDataBufferSize]; } /// <summary> /// 析構函數 /// </summary> ~SocketConnectionInfo() { DataBuffer = null; CurrentSocket = null; } public void Close() { if (CurrentSocket != null/* && CurrentSocket.Connected*/) { CurrentSocket.Close(); } } /// <summary> /// 客戶端的套接字 /// </summary> public IWebSocketConnection CurrentSocket { get; set; } /// <summary> /// 由客戶機發送緩衝區來存儲數據 /// </summary> public byte[] DataBuffer { get; set; } /// <summary> /// 當前實際接收的數據字節數,與屬性DataBuffer結合使用以肯定實際接收的數據 /// </summary> /// public int DataBufferLen { get; set; } /// <summary> /// 數據接收時的系統時間 /// </summary> public DateTime ReceivedTimeFromServer { get; set; } /// <summary> /// 最後一次接收的數據裏的採集時間 /// </summary> /// public DateTime ReceivedTimeFromClient { get; set; } /// <summary> /// 是否在線 /// </summary> public bool IsAlive { get { if (CurrentSocket != null) { return CurrentSocket.IsAvailable; } else { return false; } } } /// <summary> /// 用於標識socket鏈接 /// </summary> public string ConnectionId { get; set; } public NetStateEnum NetDataState { get; set; } public byte[] LastUnParsedBytes { get; set; } // 緩存上次未解析的數據 緩存在每一個鏈接中 public object ParsedEntity { get; set; } /// <summary> /// 是否禁用,由用戶手工更改。禁用後的鏈接不處理其收發數據,收到數據直接拋棄。防止客戶端數據高頻發送無效數據。 /// </summary> public bool IsDisabled { get; set; } public bool IsLoggedIn { get; set; } //是否登陸成功,只有登陸成功的狀況下才能夠後續通訊交互 /// <summary> /// 當前使用的終端編號,每次通訊都有可能修改 /// </summary> public string CurrentPileCode { get; set; } public string DeviceId { get; set; } public string TemporaryHint { get; set; } public string MessageTypeName { get; internal set; } } public class SocketConnectionInfoFactory { /// <summary> /// 全部客戶端Socket鏈接的集合,經過socket對象索引 /// </summary> private ConcurrentDictionary<IWebSocketConnection, SocketConnectionInfo> dictionary = new ConcurrentDictionary<IWebSocketConnection, SocketConnectionInfo>(); public ConcurrentDictionary<IWebSocketConnection, SocketConnectionInfo> GetItems() { return dictionary; } public SocketConnectionInfo BindSocketConnectionInfo(IWebSocketConnection socket, string connectionId) { SocketConnectionInfo socketConnectionInfo; if (dictionary.ContainsKey(socket)) { socketConnectionInfo = dictionary[socket]; } else { socketConnectionInfo = new SocketConnectionInfo(socket, connectionId); dictionary.TryAdd(socket, socketConnectionInfo); } return socketConnectionInfo; } public SocketConnectionInfo GetSocketConnectionInfo(string uniqueId) { SocketConnectionInfo socketConnectionInfo = null; foreach (var item in dictionary) { if (string.Compare(item.Value?.ConnectionId, uniqueId, true) == 0) { if (item.Value.ReceivedTimeFromServer >= socketConnectionInfo?.ReceivedTimeFromServer) { Remove(socketConnectionInfo.CurrentSocket); } else { socketConnectionInfo = item.Value; } } } return socketConnectionInfo; } public void Remove(IWebSocketConnection socket) { if (socket != null) { dictionary.TryRemove(socket, out SocketConnectionInfo value); try { //判斷此鏈接是否可用 if (socket.IsAvailable) { socket.Close(); } } catch { throw; } socket.Close(); value = null; } } public void RemoveAll() { foreach (var item in dictionary) { item.Value?.Close(); } dictionary.Clear(); } public int Count { get { if (dictionary == null) { return 0; } return dictionary.Count; } } } }
調用方式web
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace DB { public class DBHelper { private static object obj = new object(); private static SocketConnectionInfoFactory webSocket = null; public static SocketConnectionInfoFactory GetInstance() { if (webSocket == null) { lock (obj) { if (webSocket == null) { webSocket = new SocketConnectionInfoFactory(); } } } return webSocket; } } }