using DeviceService.Core;
|
using DeviceService.Service;
|
using System.Text.Encodings.Web;
|
using System.Text.Json;
|
using System.Text.Unicode;
|
|
namespace DeviceService.Device
|
{
|
/// <summary>
|
/// 服务正式启动后的设备管理:设备实例的内存集合、类型扫描与注册(Register)。
|
/// 设备信息的数据库读写由 <see cref="DeviceHelper"/> 负责,本类不做任何持久化。
|
/// </summary>
|
public class DeviceManager
|
{
|
|
private readonly static object _sync = new object();
|
private readonly static Dictionary<string, IDevice> _deviceCollection = new Dictionary<string, IDevice>();
|
|
public static IReadOnlyList<IDevice> Devices
|
{
|
get
|
{
|
lock (_sync)
|
{
|
return _deviceCollection.Values.ToList();
|
}
|
}
|
}
|
|
// ==================== 设备注册 ====================
|
|
/// <summary>服务启动时注册设备(内部会调用 Init),无论初始化是否成功都会加入集合。</summary>
|
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();
|
}
|
}
|
|
/// <summary>
|
/// 用数据库读取到的设备刷新内存集合(不调用 Init)。
|
/// 已存在于内存中的实例保持不变,避免丢失已注册/已打开的运行状态;
|
/// 新增记录使用传入的(从数据库还原的)实例。
|
/// </summary>
|
public static void Refresh(IEnumerable<IDevice> devices)
|
{
|
if (devices == null) throw new ArgumentNullException(nameof(devices));
|
|
lock (_sync)
|
{
|
var refreshed = new Dictionary<string, IDevice>(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<string, IDevice> pair in refreshed)
|
{
|
_deviceCollection[pair.Key] = pair.Value;
|
}
|
}
|
}
|
|
/// <summary>按 DeviceId 从内存集合移除设备(数据库记录的删除由 <see cref="DeviceHelper.RemoveDevice"/> 负责)。</summary>
|
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) {
|
|
}
|
}
|
}
|