| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177 | using FreeRedis;using Newtonsoft.Json;using ServiceCenter.Redis;namespace ServiceCenter.Virtual_PLC{    /// <summary>    /// plc数据    /// </summary>    public class PlcData    {        private static string RedisKey = "Virtual_PLC";        private static RedisClient Redis;        /// <summary>        /// 数据结构缓存        /// </summary>        private static List<PLCData> PLCDatas { get; set; } = new List<PLCData>();        /// <summary>        /// redis 链接字符串        /// </summary>        /// <param name="redisClient">Redis链接字符串</param>        public PlcData(string redisClient)        {            Redis = RedisHub.CreateContext(redisClient, RedisKey);        }        /// <summary>        /// redis 链接字符串        /// </summary>        /// <param name="redisClient"></param>        /// <returns></returns>        public static PlcData Init(string redisClient)        {            return new PlcData(redisClient);        }        /// <summary>        /// 初始化PLC数据        /// </summary>        /// <param name="pLCData">一个PLC</param>        private void InitPlcData(PLCData pLCData)        {            if (!PLCDatas.Contains(pLCData))            {                PLCDatas.Add(pLCData);            }            //用总长度除以数据长度,再以每断数据的起始位置、IP、DB组成Key            var mun = pLCData.Length / pLCData.DataLength;            int addstart = 0;            for (int i = 0; i < mun; i++)            {                var key = $"{pLCData.IP}:{pLCData.DB}:{addstart}";                if (Redis.Exists(key)) continue;                Redis.Set(key, new byte[pLCData.DataLength]);                addstart = addstart + pLCData.DataLength;            }        }        /// <summary>        /// 初始化PLC数据        /// </summary>        /// <param name="pLCDatas">多个PLC</param>        public void InitPlcData(List<PLCData> pLCDatas)        {            string key = "PLCDataList";            if (Redis.Exists(key))            {                //判断值是否相等,值相等代表已经有过数据生成了,并且没有任何变化                var RedisPlcData = Redis.Get(key);                if (JsonConvert.SerializeObject(pLCDatas) == RedisPlcData)                {                    PLCDatas = pLCDatas;                    return;                }            }            pLCDatas.ForEach(v =>            {                InitPlcData(v);            });            Redis.Set(key, JsonConvert.SerializeObject(pLCDatas));        }        /// <summary>        /// 按照DB读取        /// </summary>        /// <param name="pLCData"></param>        /// <returns></returns>        public static byte[] Read(PLCData pLCData)        {            byte[] data = new byte[pLCData.Length];            //用总长度除以数据长度,再以每断数据的起始位置、IP、DB组成Key            var mun = pLCData.Length / pLCData.DataLength;            int addstart = 0;            for (int i = 0; i < mun; i++)            {                var a = Redis.Get<byte[]>($"{pLCData.IP}:{pLCData.DB}:{addstart}");                a.CopyTo(data, addstart);                addstart = addstart + pLCData.DataLength;            }            return data;        }        /// <summary>        /// 按照长度读取        /// </summary>        /// <param name="pLCData"></param>        /// <param name="startLength">起始长度</param>        /// <returns></returns>        public static byte[] Read(PLCData pLCData, int startLength)        {            return System.Text.Encoding.Default.GetBytes(Redis.Get($"{pLCData.IP}:{pLCData.DB}:{startLength}"));        }        /// <summary>        /// 写入数据        /// </summary>        /// <param name="pLCData"></param>        /// <param name="startLength"></param>        /// <param name="value"></param>        public static void Write(PLCData pLCData, int startLength, byte[] value)        {            var data = PLCDatas.Find(v => v.IP == pLCData.IP && v.DB == pLCData.DB);            int start = 0;            if (data.DataLength == data.Length) //数据长度与总长度相等时计算            {                start = startLength < data.DataLength ? 0 : data.DataLength - startLength + startLength;            }            else //不等            {                int addstart = 0;                var mun = data.Length / data.DataLength;                var a = new List<int>();                for (int i = 0; i < mun; i++)                {                    a.Add(addstart);                    addstart = addstart + data.DataLength;                }                start = a.Where(v => v <= startLength).OrderByDescending(v => v).FirstOrDefault();                startLength = startLength - start;            }            var bytes = System.Text.Encoding.Default.GetBytes(Redis.Get($"{pLCData.IP}:{pLCData.DB}:{start}")); //获取原有数据            value.CopyTo(bytes, startLength); //将变更的数据,更新到redis字节组中            Redis.Set($"{pLCData.IP}:{pLCData.DB}:{start}", bytes);        }    }    /// <summary>    /// PLC数据结构    /// </summary>    public class PLCData    {        /// <summary>        /// IP        /// </summary>        public string IP { get; set; }        /// <summary>        /// DB        /// </summary>        public int DB { get; set; }        /// <summary>        /// 总长度        /// </summary>        public int Length { get; set; }        /// <summary>        /// 数据长度        /// </summary>        public int DataLength { get; set; }    }}
 |