TinyServer 不持有 设备管理

去掉在线持久在线列表(重启丢失),改用Device内标识 存Flash。
    Device 增加其他标识字段union{ushort,struct{位域}},目前仅有设备是否为持久在线标识,其他保留。
备注掉 V2 版本Dvice从Stream内读写函数。
修正维护设备在线bug
测试通过    (TokenClient .h .cpp  11359版本)
This commit is contained in:
WangQiang 2016-06-25 03:26:43 +00:00
parent b32ab3f6d8
commit d5ddc2d88d
7 changed files with 83 additions and 57 deletions

View File

@ -41,7 +41,7 @@ bool TinyServer::Send(Message& msg) const
// 附加目标物理地址
//if(!msg.State)
{
auto dv = DevMgmt.FindDev(((TinyMessage&)msg).Dest);
auto dv = pDevMgmt->FindDev(((TinyMessage&)msg).Dest);
if(!dv) dv = Current;
//if(dv) msg.State = dv->Mac;
if(dv) dv->Mac.CopyTo(0, msg.State, -1);
@ -70,12 +70,17 @@ void TinyServer::Start()
// 最后倒数8KB - 倒数位置4KB 的 4KB 空间
//const uint DevAddr = 0x8000000 + (Sys.FlashSize << 10) - (8 << 10);
//const uint DevSize = 4 << 10;
//DevMgmt.SetFlashCfg(DevAddr,DevSize);
//pDevMgmt->SetFlashCfg(DevAddr,DevSize);
auto count = DevMgmt.LoadDev();
if (DevicesManagement::Current)
pDevMgmt = DevicesManagement::Current;
else
pDevMgmt = new DevicesManagement();
auto count = pDevMgmt->LoadDev();
// 添加网关这一条设备信息
if (!DevMgmt.FindDev(Cfg->Address))
if (!pDevMgmt->FindDev(Cfg->Address))
{
// 如果全局设备列表内没有Server自己则添加
auto dv = new Device();
@ -86,17 +91,17 @@ void TinyServer::Start()
dv->HardID = Sys.ID;
dv->Name = Sys.Name;
// 放进持续在线表
DevMgmt.OnlineAlways.Add(dv);
//DevMgmt.PushDev(dv);
//DevMgmt.SaveDev();
DevMgmt.DeviceRequest(DeviceAtions::Register, dv);
// 标记为永久在线设备
dv->Flag.BitFlag.OnlineAlws = 1;
//pDevMgmt->PushDev(dv);
//pDevMgmt->SaveDev();
pDevMgmt->DeviceRequest(DeviceAtions::Register, dv);
}
// 注册Token控制设备列表时回调函数
DevMgmt.Register([](DeviceAtions act, const Device* dv, void *param) {((TinyServer*)(param))->DevPrsCallback(act, dv); }, this);
pDevMgmt->Register([](DeviceAtions act, const Device* dv, void *param) {((TinyServer*)(param))->DevPrsCallback(act, dv); }, this);
#if DEBUG
Sys.AddTask([](void *param) {((DevicesManagement*)(param))->ShowDev(); }, &DevMgmt, 10000, 30000, "节点列表");
Sys.AddTask([](void *param) {((DevicesManagement*)(param))->ShowDev(); }, pDevMgmt, 10000, 30000, "节点列表");
#endif
Control->Open();
@ -110,7 +115,7 @@ void TinyServer::OnReceive(TinyMessage& msg, TinyController& ctrl)
// 如果设备列表没有这个设备,那么加进去
byte id = msg.Src;
auto dv = Current;
if (!dv) dv = DevMgmt.FindDev(id);
if (!dv) dv = pDevMgmt->FindDev(id);
// 不响应不在设备列表设备的 非Join指令
if(!dv && msg.Code > 2) return;
@ -120,14 +125,14 @@ void TinyServer::OnReceive(TinyMessage& msg, TinyController& ctrl)
{
if (!OnJoin(msg)) return;
dv = Current;
DevMgmt.DeviceRequest(DeviceAtions::Online, dv);
pDevMgmt->DeviceRequest(DeviceAtions::Online, dv);
return;
}
case 2:
{
if (!OnDisjoin(msg))return;
DevMgmt.DeviceRequest(DeviceAtions::Delete, dv);
pDevMgmt->DeviceRequest(DeviceAtions::Delete, dv);
return;
}
@ -180,7 +185,7 @@ bool TinyServer::Dispatch(TinyMessage& msg)
TS("TinyServer::Dispatch");
// 先找到设备
auto dv = DevMgmt.FindDev(msg.Dest);
auto dv = pDevMgmt->FindDev(msg.Dest);
if(!dv) return false;
// 设置当前设备
@ -265,7 +270,7 @@ bool TinyServer::OnJoin(const TinyMessage& msg)
if(dm.Kind == 0x1004) return false;
// 根据硬件编码找设备
auto dv = DevMgmt.FindDev(dm.HardID);
auto dv = pDevMgmt->FindDev(dm.HardID);
if(!dv)
{
if(!Study)
@ -276,7 +281,7 @@ bool TinyServer::OnJoin(const TinyMessage& msg)
// 从1开始派ID
id = 1;
while(DevMgmt.FindDev(++id) != nullptr && id < 0xFF) { }
while(pDevMgmt->FindDev(++id) != nullptr && id < 0xFF) { }
debug_printf("发现节点设备 0x%04X ,为其分配 0x%02X\r\n", dm.Kind, id);
if(id == 0xFF) return false;
@ -312,9 +317,9 @@ bool TinyServer::OnJoin(const TinyMessage& msg)
if(dv->Valid())
{
DevMgmt.DeviceRequest(DeviceAtions::Register, dv);
//DevMgmt.PushDev(dv);
//DevMgmt.SaveDev(); // 写好相关数据 校验通过才能存flash
pDevMgmt->DeviceRequest(DeviceAtions::Register, dv);
//pDevMgmt->PushDev(dv);
//pDevMgmt->SaveDev(); // 写好相关数据 校验通过才能存flash
}
else
{
@ -372,7 +377,7 @@ bool TinyServer::OnDisjoin(const TinyMessage& msg)
// 如果是退网请求,这里也需要删除设备
if(!msg.Reply)
{
auto dv = DevMgmt.FindDev(msg.Src);
auto dv = pDevMgmt->FindDev(msg.Src);
if(dv)
{
// 拿出来硬件ID的校验检查是否合法
@ -414,7 +419,7 @@ bool TinyServer::Disjoin(byte id)
{
TS("TinyServer::Disjoin");
auto dv = DevMgmt.FindDev(id);
auto dv = pDevMgmt->FindDev(id);
auto crc = Crc::Hash16(dv->HardID);
TinyMessage msg;
@ -425,7 +430,7 @@ bool TinyServer::Disjoin(byte id)
msg.Length = ms.Position();
Send(msg);
DevMgmt.DeviceRequest(DeviceAtions::Delete,id);
pDevMgmt->DeviceRequest(DeviceAtions::Delete,id);
return true;
}
@ -434,7 +439,7 @@ bool TinyServer::OnPing(const TinyMessage& msg)
{
TS("TinyServer::OnPing");
auto dv = DevMgmt.FindDev(msg.Src);
auto dv = pDevMgmt->FindDev(msg.Src);
// 网关内没有相关节点信息时不鸟他
if(dv == nullptr) return false;
@ -629,12 +634,12 @@ void TinyServer::ClearDevices()
TS("TinyServer::ClearDevices");
debug_printf("准备清空设备,发送 Disjoin");
int count = DevMgmt.Length();
int count = pDevMgmt->Length();
for(int j = 0; j < 3; j++) // 3遍
{
for(int i = 1; i < count; i++) // 从1开始派ID 自己下线完全不需要
{
auto dv = (Device*)DevMgmt.DevArr[i];
auto dv = (Device*)pDevMgmt->DevArr[i];
if(!dv) continue;
TinyMessage rs;
@ -645,7 +650,7 @@ void TinyServer::ClearDevices()
}
}
debug_printf("\r\n发送 Disjoin 完毕\r\n");
DevMgmt.ClearDev();
pDevMgmt->ClearDev();
}
void TinyServer::DevPrsCallback(DeviceAtions act, const Device * dv)

View File

@ -35,7 +35,7 @@ public:
void* Param;
//TinyServer 有足够的理由持有设备列表
DevicesManagement DevMgmt;
DevicesManagement *pDevMgmt;
// 删除列表时候需要发送Disjoin消息 所以保留次函数
void ClearDevices();
// 云端处理设备时候回调

View File

@ -9,22 +9,23 @@ Device::Device() :
Pass(_Pass, sizeof(_Pass)),
Store(_Store, sizeof(_Store))
{
Address = 0;
Logined = false;
Address = 0;
Logined = false;
Kind = 0;
LastTime = 0;
RegTime = 0;
LoginTime = 0;
Logins = 0;
Kind = 0;
LastTime = 0;
RegTime = 0;
LoginTime = 0;
Logins = 0;
Version = 0;
DataSize = 0;
ConfigSize = 0;
Version = 0;
DataSize = 0;
ConfigSize = 0;
PingTime = 0;
PingTime = 0;
OfflineTime = 0;
SleepTime = 0;
SleepTime = 0;
Flag.Data = 0;
HardID.Clear();
Mac.Clear();
@ -32,9 +33,9 @@ Device::Device() :
Pass.Clear();
Store.Clear();
Cfg = nullptr;
Cfg = nullptr;
LastRead = 0;
LastRead = 0;
//LastWrite = 0;
}
@ -64,6 +65,7 @@ void Device::Read(Stream& ms)
ms.SetPosition(p + len);
}
/*
void Device::WriteMessage(Stream& ms) const
{
byte* buf = ms.Current();
@ -114,6 +116,7 @@ void Device::ReadMessage(Stream& ms)
// 最后位置
ms.SetPosition(p + size);
}
*/
bool Device::Valid() const
{
@ -153,6 +156,10 @@ String& Device::ToStr(String& str) const
str += "\t";
str += Name;
}
if (Flag.BitFlag.OnlineAlws)
{
str += " 持久在线设备";
}
return str;
}
#endif

View File

@ -8,6 +8,17 @@
/******************************** Device ********************************/
union DevFlag
{
ushort Data;
struct
{
ushort OnlineAlws : 1; // 持久在线
ushort Reserved : 15; // 保留
}BitFlag;
};
// 设备信息
class Device : public Object
{
@ -16,7 +27,7 @@ public:
byte Address; // 节点地址
ushort Kind; // 类型
byte _HardID[16]; // 硬件编码
byte _HardID[16];// 硬件编码
uint LastTime; // 活跃时间。秒
uint RegTime; // 注册时间。秒
uint LoginTime; // 登录时间。秒
@ -30,10 +41,11 @@ public:
ushort OfflineTime;// 离线阀值时间。秒
ushort PingTime; // 心跳时间。秒
byte _Mac[6]; // 无线物理地址
byte _Mac[6]; // 无线物理地址
char _Name[16]; // 名称
//String Name; //变长名称
//String Name; // 变长名称
byte _Pass[8]; // 通信密码
DevFlag Flag; // 其他状态
// 在Tiny网络下 作为设备的数据区的网关备份 加快访问速度
// 在Token网络下 直接作为虚拟设备的数据区
@ -57,9 +69,10 @@ public:
// 序列化到消息数据流
void Write(Stream& ms) const;
void Read(Stream& ms);
/*
void WriteMessage(Stream& ms) const;
void ReadMessage(Stream& ms);
*/
bool CanSleep() const { return SleepTime > 0; }
bool Valid() const;

View File

@ -102,8 +102,8 @@ bool DevicesManagement::DeleteDev(byte id)
if (idx >= 0)DevArr[idx] = nullptr;
// 处理持久在线表
int idx2 = OnlineAlways.FindIndex(dv);
if (idx2 >= 0)OnlineAlways[idx2] = nullptr;
// int idx2 = OnlineAlways.FindIndex(dv);
// if (idx2 >= 0)OnlineAlways[idx2] = nullptr;
delete dv;
SaveDev();
@ -570,20 +570,21 @@ void DevicesManagement::DeviceRequest(DeviceAtions act, const Device* dv)
void DevicesManagement::MaintainState()
{
if (Port)return;
if (!Port)return;
if (Port->Status < 2) return;
SendDevicesIDs();
auto now = Sys.Seconds();
//auto now = Sys.Seconds();
auto now = DateTime::Now().TotalSeconds();
// 处理持久在线设备
for (int i = 0; i < OnlineAlways.Count(); i++)
byte len = Length();
for (int i = 0; i < len; i++)
{
auto dv = (Device*)OnlineAlways[i];
if (dv) dv->LastTime = now;
auto dv = (Device*)DevArr[i];
if (dv && dv->Flag.BitFlag.OnlineAlws == 1)dv->LastTime = now;
}
byte len = Length();
for (int i = 0; i < len; i++)
{
auto dv = (Device*)DevArr[i];

View File

@ -45,7 +45,7 @@ public:
// 设备列表
List DevArr;
// 持久在线列表
List OnlineAlways;
// List OnlineAlways;
TokenClient * Port = nullptr;
// 发送时刻再绑定?! 如果绑定失败报错?

View File

@ -76,8 +76,8 @@ void Gateway::Start()
dv->Name = Sys.Name;
//pDevMgmt->PushDev(dv);
// 放进持续在线表
pDevMgmt->OnlineAlways.Add(dv);
// 标记为永久在线设备
dv->Flag.BitFlag.OnlineAlws = 1;
pDevMgmt->DeviceRequest(DeviceAtions::Register, dv);
}