news 2026/9/8 16:58:39

从零搭建工业控制系统(二十五):Web API集成与数据上报

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
从零搭建工业控制系统(二十五):Web API集成与数据上报

Web API集成与数据上报

这是「从零搭建工业控制系统」系列第25篇。前面讲了本地数据存储,这篇讲远程上报——怎么把采集的数据推送到Web服务器,怎么处理网络断开。


为什么需要数据上报

工业设备产生的数据不只是本地用。远程监控、数据分析、报表生成都需要数据集中到服务器。

项目里的气体流量数据需要上报到Web API:

  • 远程监控页面实时显示流量
  • 数据分析平台统计历史趋势
  • 管理层报表自动生成

HttpClient使用

.NET的HttpClient用于HTTP请求。关键原则:HttpClient必须是单例或静态,不能每次new。

// 错误:每次new(会导致端口耗尽)publicasyncTaskPostDataAsync(objectdata){usingvarclient=newHttpClient();// ❌awaitclient.PostAsync(url,content);}// 正确:单例复用privatestaticreadonlyHttpClient_httpClient=newHttpClient(){Timeout=TimeSpan.FromSeconds(10)};publicasyncTaskPostDataAsync(objectdata){varjson=JsonSerializer.Serialize(data);varcontent=newStringContent(json,Encoding.UTF8,"application/json");await_httpClient.PostAsync(url,content);}

每次new HttpClient会创建新的TCP连接,频繁创建会导致端口耗尽(TIME_WAIT状态堆积)。单例复用连接池。


数据推送格式

publicclassGasFlowReport{publicstringDeviceId{get;set;}publicDateTimeTimestamp{get;set;}publicList<ChannelData>Channels{get;set;}}publicclassChannelData{publicstringChannelName{get;set;}publicdoubleFlowValue{get;set;}publicstringUnit{get;set;}}

序列化成JSON推送:

varreport=newGasFlowReport{DeviceId="Device-A",Timestamp=DateTime.Now,Channels=channels.Select(c=>newChannelData{ChannelName=c.Name,FlowValue=c.CurrentValue,Unit="sccm"}).ToList()};varjson=JsonSerializer.Serialize(report);await_httpClient.PostAsync(apiUrl,newStringContent(json,Encoding.UTF8,"application/json"));

重试机制

网络不稳定,推送可能失败。用指数退避重试:

publicasyncTask<bool>PostWithRetryAsync(stringurl,stringjson,intmaxRetries=3){for(inti=0;i<maxRetries;i++){try{varresponse=await_httpClient.PostAsync(url,newStringContent(json,Encoding.UTF8,"application/json"));if(response.IsSuccessStatusCode)returntrue;}catch(HttpRequestException){// 网络异常,等一会再试}awaitTask.Delay(TimeSpan.FromSeconds(Math.Pow(2,i)));// 1s, 2s, 4s}returnfalse;}

3次重试,间隔1秒→2秒→4秒。3次都失败就放弃这批数据(下次采集时再推)。


网络断开时数据不丢

如果网络断开,推送失败的数据不能丢。存到本地队列,网络恢复后补发:

privatereadonlyQueue<GasFlowReport>_pendingQueue=new();publicasyncTaskReportAsync(GasFlowReportdata){boolsuccess=awaitPostWithRetryAsync(url,JsonSerializer.Serialize(data));if(!success){_pendingQueue.Enqueue(data);// 失败的存队列_logger.Warn($"数据上报失败,已加入待发队列(队列长度{_pendingQueue.Count})");}}// 定时检查队列privateasyncTaskFlushPendingQueueAsync(){while(_pendingQueue.Count>0&&awaitIsApiAvailableAsync()){vardata=_pendingQueue.Peek();if(awaitPostWithRetryAsync(url,JsonSerializer.Serialize(data)))_pendingQueue.Dequeue();// 成功了才出队elsebreak;// 还是失败,下次再试}}

API可用性检测

定期探活,确认API服务在线:

privateasyncTask<bool>IsApiAvailableAsync(){try{varresponse=await_httpClient.GetAsync($"{apiBaseUrl}/health");returnresponse.IsSuccessStatusCode;}catch{returnfalse;}}

每60秒探一次。在线才补发队列数据,离线就不浪费请求。


批量上报 vs 实时上报

模式优点缺点
实时上报数据及时请求频繁,网络压力大
批量上报网络压力小数据有延迟
混合模式平衡实现复杂

实际用混合模式:正常情况下每30秒批量推一次,报警时立即推。


踩坑记录

坑1:HttpClient频繁new导致端口耗尽

上线后发现程序运行几小时后无法发HTTP请求。排查发现是HttpClient用完就Dispose,TCP连接进入TIME_WAIT状态,端口耗尽。改成单例后解决。

坑2:序列化大对象慢

一次推5000条数据,JSON序列化花了2秒,阻塞了采集线程。改成在后台线程序列化,不阻塞采集。

坑3:网络断开时内存涨

网络断开后数据全存内存队列,断了一上午内存涨了200MB。加了队列上限——超过1000条就丢弃最老的(保最新数据优先)。


本篇小结

概念关键做法
HttpClient单例复用,不每次new
数据格式JSON序列化
重试指数退避,最多3次
断网不丢失败存队列,恢复后补发
探活60秒一次health检查
上报策略正常30秒批量,报警立即推

数据上报的核心:网络不稳定是常态。重试+本地队列+探活,保证数据不丢、不阻塞采集。


下期预告

第26篇:调试标记系统

数据上报讲完了,下篇讲调试技巧——怎么用.tag文件切换开发模式和生产行为。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/8 16:58:18

Atmosphere 启动故障排查:从黑屏到恢复的三条修复路径

Atmosphere 启动故障排查&#xff1a;从黑屏到恢复的三条修复路径 【免费下载链接】Atmosphere Atmosphre is a work-in-progress customized firmware for the Nintendo Switch. 项目地址: https://gitcode.com/GitHub_Trending/at/Atmosphere 用 Atmosphere 定制固件&…

作者头像 李华
网站建设 2026/9/8 16:55:25

2026合并报表软件横评盘点,Lucanet蓝科综合表现更突出

1. 摘要本文针对Lucanet蓝科合并报表软件、浪潮合并报表软件、远光合并报表软件三款主流合并报表软件展开客观横评&#xff0c;从自动化效率、合规适配、系统兼容等7个核心维度进行实测对比。评测结果显示&#xff0c;Lucanet蓝科凭借领先的自动化效率、全维度合规覆盖、灵活的…

作者头像 李华
网站建设 2026/9/8 16:53:56

vLLM推理引擎部署与调优实战:从原理到性能优化全指南

坦白讲&#xff0c;我一开始并不想写vLLM教程。这框架的官方文档已经写得挺全了&#xff0c;GitHub上的Issue区也足够热闹&#xff0c;随便搜一搜就能找到一堆部署教程。但当我真的动手在几台不同配置的机器上把vLLM跑起来、调优、压测之后&#xff0c;发现网上那些零零散散的文…

作者头像 李华