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; } } }