using DeviceService.Core;
using DeviceService.Service;
using System.Text.Encodings.Web;
using System.Text.Json;
using System.Text.Unicode;
namespace DeviceService.Device
{
///
/// 服务正式启动后的设备管理:设备实例的内存集合、类型扫描与注册(Register)。
/// 设备信息的数据库读写由 负责,本类不做任何持久化。
///
public class DeviceManager
{
private readonly static object _sync = new object();
private readonly static Dictionary _deviceCollection = new Dictionary();
public static IReadOnlyList Devices
{
get
{
lock (_sync)
{
return _deviceCollection.Values.ToList();
}
}
}
// ==================== 设备注册 ====================
/// 服务启动时注册设备(内部会调用 Init),无论初始化是否成功都会加入集合。
public static bool Register(IDevice device, out string msg)
{
if (device == null) throw new ArgumentNullException(nameof(device));
bool initOk = device.Init(out msg);
if (initOk)
{
lock (_sync)
{
_deviceCollection[device.DeviceId] = device;
}
}
return initOk;
}
public static void UnRegisterAll()
{
lock (_sync)
{
_deviceCollection.Clear();
}
}
///
/// 用数据库读取到的设备刷新内存集合(不调用 Init)。
/// 已存在于内存中的实例保持不变,避免丢失已注册/已打开的运行状态;
/// 新增记录使用传入的(从数据库还原的)实例。
///
public static void Refresh(IEnumerable devices)
{
if (devices == null) throw new ArgumentNullException(nameof(devices));
lock (_sync)
{
var refreshed = new Dictionary(StringComparer.Ordinal);
foreach (IDevice device in devices)
{
if (device == null || string.IsNullOrWhiteSpace(device.DeviceId))
{
continue;
}
refreshed[device.DeviceId] = _deviceCollection.TryGetValue(device.DeviceId, out IDevice? existing)
? existing
: device;
}
_deviceCollection.Clear();
foreach (KeyValuePair pair in refreshed)
{
_deviceCollection[pair.Key] = pair.Value;
}
}
}
/// 按 DeviceId 从内存集合移除设备(数据库记录的删除由 负责)。
public static bool Remove(string id)
{
lock (_sync)
{
return _deviceCollection.Remove(id);
}
}
private static readonly JsonSerializerOptions SafeOptions = new()
{
Encoder = JavaScriptEncoder.Create(UnicodeRanges.All)
};
public static void HandleClientMessage(RequestArg arg)
{
var data = arg.Data;
string deviceId = data.DeviceId;
if (_deviceCollection.TryGetValue(deviceId, out IDevice device))
{
var res = device.HandleRequest(data);
arg.Client.Send(JsonSerializer.Serialize(res, SafeOptions), out _);
}
else
{
var res = new ResponseData
{
Success = false,
Message = "无效的DeviceId"
};
arg.Client.Send(JsonSerializer.Serialize(res, SafeOptions), out _);
}
}
public static void ReleaseClient(IClient client) {
}
}
}