API正在混合来自不同设备的数据

时间:2018-11-01 10:36:30

标签: c# asp.net-mvc asynchronous api-design

我有一个API,该API的设备可以同时或在几毫秒内向其发送数据。我发现的是数据变得混乱了。数据每五分钟发送一次(在时钟05、10、15等处)。我有一个执行过滤器,用于捕获传入的URL数据,因此我始终有一个真实的源,然后将其传递到端点,然后再进行处理。例如,将随机缺少五分钟。当我使用执行过滤器中缺少的URL逐步调试时,它可以正常工作。我的意思是,我获取URL并进行调试,然后将其插入。

总而言之,我有设备ID 1和设备ID2。即使我看到数据已经击中执行过滤器,我也会丢失间隔。

我假设API不会将它们作为单独的事务处理,而是以某种方式将它们混合在一起,因此丢失了数据,并且序列号出现在错误的位置,从而ID 1中的数据出现在ID 2中反之亦然

API端点:

public class SomeController : ApiController
    {          
        [HttpGet]       
        [ExecutionFilter]   
        public async Task<HttpResponseMessage> Get([FromUri] FixedDataModel fdm)
        {
            var reply = new HttpResponseMessage();
            string url = HttpUtility.UrlDecode(HttpContext.Current.Request.QueryString.ToString());

            if (url.Contains("timestamp"))
            {
                reply = TimeSyncValidation.TimeSync;
                return reply;
            }
            else if (!url.Contains("timestamp"))
            {                
                reply = await Task.Run(() => DeviceClass.DeviceApiAsync(fdm, url));               
            }

            return reply;
        }       
    }

处理类:

namespace API.Services
{
    public class DeviceClass
    {
        private static string serialNumber;
        private static byte chk;
        private static string channelName, channelReadingNumber, channelValue, queryString, readingDate;
        private static int colonPosition, chanCountFrom, equalsPosition;
        private static bool checkSumCorrect;

        public static HttpResponseMessage DeviceApiAsync(FixedDataModel fdm, string urlQqueryString)
        {
            Guid guid = Guid.NewGuid();
            //ExecutionTrackerHandler.Guid = guid;

            //Remove question mark
            var q = urlQqueryString;
            queryString = q.Substring(0);

            var items = HttpUtility.ParseQueryString(queryString);
            serialNumber = items["se"];

            //Store raw uri for fault finding
            var rawUri = new List<RawUriModel>
            {
                new RawUriModel
                {
                    UniqueId = guid,
                    RawUri = q,
                    TimeStamp = DateTime.Now
                }
            };

            //Checksum validation
            chk = Convert.ToByte(fdm.chk);

            checkSumCorrect = CheckSumValidator.XorCheckSum(queryString, chk);
            if (!checkSumCorrect)
            {
                return ValidationResponseMessage.ResponseHeaders("Checksum");
            }

            //Create list of items that exist in URL
            var urldata = new UrlDataList
            {
                UrlData = queryString.Split('&').ToList(),
            };

            var data = new List<UriDataModel>();

            //Split the URL string into its parts
            foreach (var item in urldata.UrlData)
            {
                colonPosition = item.IndexOf(":");
                chanCountFrom = colonPosition + 1;
                equalsPosition = item.LastIndexOf("=");

                if (colonPosition == -1)
                {
                    channelName = item.Substring(0, equalsPosition);
                    channelReadingNumber = "";
                    channelValue = item.Substring(item.LastIndexOf("=") + 1);
                }
                else
                {
                    channelName = item.Substring(0, colonPosition);
                    channelReadingNumber = item.Substring(chanCountFrom, equalsPosition - chanCountFrom);
                    channelValue = item.Substring(item.LastIndexOf("=") + 1);

                    if (channelName == "atime" || channelName == "adate")
                    {
                        readingDate = DateValidator.CreateDate(channelValue);
                    }
                };

                bool nullFlag = false;
                if (channelValue == null)
                    nullFlag = true;

                bool missingFlag = false;
                if (channelValue == "x") {
                    missingFlag = true;
                    channelValue = "0";
                }

                //Add data to model ready for DB insert.
                data.Add(new UriDataModel
                {
                    uid = guid,
                    SerialNumber = serialNumber,
                    ChannelName = channelName,
                    ChannelReadingNumber = channelReadingNumber,
                    ChannelValue = channelValue.Replace(",", "."),
                    ReadingDate = readingDate,
                    TimeStamp = DateTime.Now.ToString("yyyy-MM-dd HH:mm"),
                    Processed = false,
                    NullFlag = nullFlag,
                    MissingFlag = missingFlag
                });
            };

            //Validate dates
            var allDates = (from x in data where x.ChannelName.Contains("atime") || x.ChannelName.Contains("adate") select x.ChannelValue).ToList();
            bool dateValidation = DateValidator.IsValid(allDates);
            if (!dateValidation)
            {
                return ValidationResponseMessage.ResponseHeaders("Date");
            };

            //Validate values
            var channels = Enum.GetNames(typeof(Channels)).ToList();
            List<string> allChannelValues = data.Where(d => channels.Contains(d.ChannelName)).Select(d => d.ChannelValue).ToList();
            bool valueValidation = ValueValidator.IsValid(allChannelValues);
            if (!valueValidation)
            {
                return ValidationResponseMessage.ResponseHeaders("Values");
            };

            //Insert live data
            var insertData = DataInsert<UriDataModel>.InsertData(data, "Staging.UriData");
            if (!insertData)
            {
                return ValidationResponseMessage.ResponseHeaders("Sql");
            }

            var content = "\r\nSUCCESS\r\n";
            var reply = new HttpResponseMessage(System.Net.HttpStatusCode.OK)
            {
                Content = new StringContent(content)
            };

            return reply;
        }
    }
}

TIA

1 个答案:

答案 0 :(得分:3)

您正在使用全局变量和静态方法来处理数据。 将您的方法更改为非静态。 每个DeviceClass工作人员必须仅更新自己的隔离数据,然后将其推回控制器。