现在每采集一次都会推送数据,消息量就会比较大,而且点位状态不变化,也会一直推送,会占用消耗大量资源
变化推送
所以我们要实现变化推送,实现的逻辑也比较简单,存下上一次的值,跟这次值比较,如果不一样就更新+推送
实现方法
这就需要对历史的数据值进行缓存
可以有几种方法:
- 在RegisterPoint中的Value存储并判断
- 添加一个键值对存储点ID 和值的关系,用于快速查找
private Dictionary<string,object> PointValues= new Dictionary<string,object>();
- 使用redis进行缓存
前两种方法本质都是一样的,在程序中添加字段直接存储,好处就是代码简单,实现方便,缺点就是程序挂了,值就丢失了,需要重启后重新读一次才有
后一种就是用Redis,优点就是开启持久化之后,程序挂了值还有保存,缺点就是需要额外部署和增加额外代码
现在暂时使用第一种。
实现
代码上实现也很简单,在处理完数据之后,进行一个判断,值不一样才进行赋值
下面这样写,无法实现
if (value!= point.Value)
{
point.Value = value;
ValueUpdated?.Invoke(point, value);
}
两个值类型一样,数值也一样,但是不相等,因为他们都是object类型,是引用类型,是两个不同的对象,所以是不相等的,可以看到当进行到下面
/// <summary>
/// 数据处理方法
/// </summary>
/// <param name="point"></param>
/// <param name="bytes"></param>
void DealData(RegisterPoint point, byte[] bytes)
{
//...处理过程
//赋值
if (value!= point.Value)
{
point.Value = value;
ValueUpdated?.Invoke(point, value);
}
// Console.WriteLine($"Point:{point.UID}-->Value:{value}");
}
改用Equals判断
if (!value.Equals(point.Value))
{
point.Value = value;
ValueUpdated?.Invoke(point, value);
}
true
如果obj
是Int16的实例,并且等于该实例的值;否则false
现在就没有一直推送了,只有变化才增加一个点推送