You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
754 lines
28 KiB
754 lines
28 KiB
using Application.Domain.Entities;
|
|
using Application.Models;
|
|
using Infrastructure.Data;
|
|
using Infrastructure.Extensions;
|
|
using Infrastructure.Models;
|
|
using Microsoft.AspNetCore.Hosting;
|
|
using Microsoft.Extensions.Configuration;
|
|
using Microsoft.Extensions.DependencyInjection;
|
|
using System;
|
|
using System.Collections.Concurrent;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Net;
|
|
using System.Net.Http;
|
|
using System.Net.NetworkInformation;
|
|
using System.Net.Sockets;
|
|
using System.Text;
|
|
using System.Text.RegularExpressions;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
|
|
namespace FBeeService
|
|
{
|
|
public class DeviceService : IDisposable
|
|
{
|
|
private readonly IHostingEnvironment _env;
|
|
private readonly IConfiguration _configuration;
|
|
private readonly IHttpClientFactory _httpClientFactory;
|
|
private readonly IServiceProvider _applicationServices;
|
|
private CancellationTokenSource _tokenSource;
|
|
private static readonly object lockObject = new Object();
|
|
private string _tcpIp;
|
|
private int _tcpPort;
|
|
private byte[] _address;
|
|
private string _addressValue;
|
|
private readonly Dictionary<int, int> _types = new Dictionary<int, int>();
|
|
private readonly ConcurrentDictionary<string, TcpClientWrapper> Clients = new ConcurrentDictionary<string, TcpClientWrapper>();
|
|
|
|
public DeviceService(IHostingEnvironment env, IServiceProvider applicationServices, IConfiguration configuration, IHttpClientFactory httpClientFactory)
|
|
{
|
|
this._env = env;
|
|
this._applicationServices = applicationServices;
|
|
this._configuration = configuration;
|
|
this._httpClientFactory = httpClientFactory;
|
|
this._tokenSource = new CancellationTokenSource();
|
|
this._tcpIp = this._configuration["tcp.ip"];
|
|
this._tcpPort = this._configuration.GetValue<int>("tcp.port");
|
|
//this.Connect();
|
|
}
|
|
|
|
public void Start()
|
|
{
|
|
Task.Run(async () =>
|
|
{
|
|
while (!_tokenSource.IsCancellationRequested)
|
|
{
|
|
try
|
|
{
|
|
Console.WriteLine("timer ...");
|
|
Refresh();
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
ex.PrintStack();
|
|
}
|
|
await Task.Delay(this._configuration.GetValue<int>("timer.seconds") * 1000);
|
|
}
|
|
});
|
|
}
|
|
|
|
public void Refresh()
|
|
{
|
|
Console.WriteLine("notify start ...");
|
|
try
|
|
{
|
|
this.CheckConnection();
|
|
//this.SearchAddress();
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
ex.PrintStack();
|
|
}
|
|
Console.WriteLine("notify end ...");
|
|
}
|
|
|
|
#region api
|
|
|
|
/// <summary>
|
|
/// 0x81获取当前连接所有设备
|
|
/// </summary>
|
|
/// <param name="sn"></param>
|
|
public void X81(string sn)
|
|
{
|
|
Console.WriteLine($"refresh {sn}");
|
|
this.Write(sn, RequestType.x81, null);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 接收当前连接的设备信息
|
|
/// </summary>
|
|
/// <param name="sn"></param>
|
|
/// <param name="data"></param>
|
|
private void X01(string sn, byte[] data)
|
|
{
|
|
try
|
|
{
|
|
using (var ms = new MemoryStream(data))
|
|
{
|
|
var responseType = ms.ReadByte();
|
|
var dataLength = ms.ReadByte();
|
|
var address = ms.ReadHexString(2);
|
|
var endpoint = ms.ReadByte();
|
|
using (var scope = _applicationServices.CreateScope())
|
|
{
|
|
var profileId = ms.ReadInt();
|
|
var deviceId = ms.ReadInt();
|
|
var deviceType = DeviceId.List.FirstOrDefault(o => o.RawDeviceId == deviceId);
|
|
if (deviceType != null)
|
|
{
|
|
var deviceRepo = scope.ServiceProvider.GetService<IRepository<FBeeDevice>>();
|
|
var device = deviceRepo.Table().FirstOrDefault(o => o.Sn == sn && o.Address == address);
|
|
if (device == null)
|
|
{
|
|
device = new FBeeDevice
|
|
{
|
|
Sn = sn,
|
|
Name = deviceType.Name,
|
|
EName = deviceType.EName,
|
|
Icon = deviceType.Icon,
|
|
CategoryNumber = deviceType.RawDeviceId,
|
|
CategoryName = deviceType.Category
|
|
};
|
|
deviceRepo.Add(device);
|
|
}
|
|
device.DataType = responseType;
|
|
device.DataLength = dataLength;
|
|
device.Address = address;
|
|
device.Endpoint = endpoint;
|
|
device.ProfileId = profileId;
|
|
device.DeviceId = deviceId;
|
|
device.SwitchState = ms.ReadByte();
|
|
device.NameLength = ms.ReadByte();
|
|
if (device.NameLength > 0)
|
|
{
|
|
device.CName = ms.ReadASIIString(device.NameLength);
|
|
}
|
|
device.IsOnline = ms.ReadByte();
|
|
device.IEEE = ms.ReadHexString(8);
|
|
device.SNLength = ms.ReadByte();
|
|
device.RawSN = ms.ReadHexString(device.SNLength);
|
|
device.ZoneType = ms.ReadInt();
|
|
if (device.DeviceId == 0x402)
|
|
{
|
|
if (device.ZoneType == 0x0028)
|
|
{
|
|
device.Name = "烟雾传感器";
|
|
}
|
|
else if (device.ZoneType == 0x000d)
|
|
{
|
|
device.Name = "红外感应器";
|
|
}
|
|
}
|
|
device.Battery = ms.ReadByte();
|
|
device.EpCount = ms.ReadByte();
|
|
device.Data = ms.ReadHexString(4);
|
|
device.RawValue = BitConverter.ToString(data);
|
|
deviceRepo.SaveChanges();
|
|
}
|
|
else
|
|
{
|
|
Console.WriteLine("uknown device type");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Console.WriteLine(ex.Message);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 0x95删除指定设备
|
|
/// </summary>
|
|
/// <param name="sn"></param>
|
|
/// <param name="ieee"></param>
|
|
public void X95(string sn, string ieee)
|
|
{
|
|
Console.WriteLine($"delete {ieee} from {sn}");
|
|
this.Clients.TryGetValue(sn, out TcpClientWrapper client);
|
|
using (var scope = _applicationServices.CreateScope())
|
|
{
|
|
var repo = scope.ServiceProvider.GetService<IRepository<FBeeDevice>>();
|
|
var device = repo.ReadOnlyTable().FirstOrDefault(o => o.IsOnline != 0 && o.IEEE == ieee);
|
|
var address = device.Address;
|
|
var list = new List<byte>();
|
|
list.Add(0x0c);
|
|
list.Add(0x02);
|
|
list.AddRange(address.HexToBytes());
|
|
list.AddRange(ieee.HexToBytes());
|
|
list.Add(0x01);
|
|
this.Write(sn, RequestType.x95, list);
|
|
}
|
|
}
|
|
|
|
//0x94更改指定设备名
|
|
/// <summary>
|
|
/// 0x82设置指定设备的开关状态
|
|
/// </summary>
|
|
/// <param name="sn"></param>
|
|
/// <param name="ieee"></param>
|
|
/// <param name="status"></param>
|
|
public void X82(string sn, string ieee, byte status)
|
|
{
|
|
using (var scope = _applicationServices.CreateScope())
|
|
{
|
|
var repo = scope.ServiceProvider.GetService<IRepository<FBeeDevice>>();
|
|
var device = repo.ReadOnlyTable().FirstOrDefault(o => o.Sn == sn && o.IEEE == ieee);
|
|
if (device != null)
|
|
{
|
|
var address = device.Address;
|
|
var list = new List<byte>();
|
|
list.Add(0x0d);
|
|
list.Add(0x02);
|
|
list.AddRange(address.HexToBytes());
|
|
list.AddRange(new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 });
|
|
list.Add((byte)device.Endpoint);
|
|
list.AddRange(new byte[] { 0x00, 0x00 });
|
|
list.Add(status);
|
|
this.Write(sn, RequestType.x82, list);
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 0x07接收指定设备的开关状态
|
|
/// </summary>
|
|
/// <param name="sn"></param>
|
|
/// <param name="data"></param>
|
|
private void X07(string sn, byte[] data)
|
|
{
|
|
using (var ms = new MemoryStream(data))
|
|
{
|
|
var responseType = ms.ReadByte();
|
|
var dataLength = ms.ReadByte();
|
|
var address = ms.ReadHexString(2);
|
|
var endpoint = ms.ReadByte();
|
|
using (var scope = _applicationServices.CreateScope())
|
|
{
|
|
var deviceRepo = scope.ServiceProvider.GetService<IRepository<FBeeDevice>>();
|
|
var device = deviceRepo.Table().FirstOrDefault(o => o.Sn == sn && o.Address == address);
|
|
if (device != null)
|
|
{
|
|
device.SwitchState = ms.ReadInt();
|
|
deviceRepo.SaveChanges();
|
|
}
|
|
else
|
|
{
|
|
Console.WriteLine($"device {address} hasn't save in database");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 0x83设置指定设备的亮度
|
|
/// </summary>
|
|
/// <param name="sn"></param>
|
|
/// <param name="ieee"></param>
|
|
/// <param name="value">0-255</param>
|
|
public void X83(string sn, string ieee, byte value)
|
|
{
|
|
using (var scope = _applicationServices.CreateScope())
|
|
{
|
|
var repo = scope.ServiceProvider.GetService<IRepository<FBeeDevice>>();
|
|
var device = repo.ReadOnlyTable().FirstOrDefault(o => o.Sn == sn && o.IEEE == ieee);
|
|
if (device != null)
|
|
{
|
|
var address = device.Address;
|
|
var list = new List<byte>();
|
|
list.AddRange(sn.HexToBytes().Reverse());
|
|
list.Add(RequestType.xfe);
|
|
list.Add(RequestType.x82);
|
|
list.Add(0x0d);
|
|
list.Add(0x02);
|
|
list.AddRange(address.HexToBytes());
|
|
list.AddRange(new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 });
|
|
list.Add(0x01);
|
|
list.AddRange(new byte[] { 0x00, 0x00 });
|
|
list.Add(value);
|
|
list.AddRange(new byte[] { 0x00, 0x00 });
|
|
this.Write(sn, RequestType.x82, list);
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 0x29接收指定设备的亮度
|
|
/// </summary>
|
|
/// <param name="sn"></param>
|
|
/// <param name="data"></param>
|
|
private void X29(string sn, byte[] data)
|
|
{
|
|
using (var ms = new MemoryStream(data))
|
|
{
|
|
var responseType = ms.ReadByte();
|
|
var dataLength = ms.ReadByte();
|
|
}
|
|
}
|
|
|
|
//0x84
|
|
//0x85
|
|
|
|
//0x86
|
|
//0x87
|
|
//0x88
|
|
//0x8d
|
|
//0x96
|
|
//0x8e
|
|
//0x8f
|
|
//0x97
|
|
//0x98
|
|
//0x90
|
|
//0x91
|
|
//0x92
|
|
//0x93
|
|
//0x8a
|
|
//0x8b
|
|
//0x8c
|
|
//0x99
|
|
//0x9a
|
|
//0x9b
|
|
//0x9c
|
|
//0x9d获取网关信息
|
|
public void X9d(string sn)
|
|
{
|
|
this.Write(sn, RequestType.x9d, null);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 0x15接收网关信息
|
|
/// </summary>
|
|
/// <param name="sn"></param>
|
|
/// <param name="data"></param>
|
|
private void X15(string sn, byte[] data)
|
|
{
|
|
using (var ms = new MemoryStream(data))
|
|
{
|
|
var responseType = ms.ReadByte();
|
|
var dataLength = ms.ReadByte();
|
|
var version = ms.ReadASIIString(5);
|
|
var snid = ms.ReadHexString(4);
|
|
using (var scope = _applicationServices.CreateScope())
|
|
{
|
|
var gatewayRepo = scope.ServiceProvider.GetService<IRepository<Gateway>>();
|
|
var gateway = gatewayRepo.Table().FirstOrDefault(o => o.Sn == sn);
|
|
if (gateway == null)
|
|
{
|
|
Console.WriteLine($"gateway {sn} hasn't save in database");
|
|
}
|
|
else
|
|
{
|
|
gateway.Version = version;
|
|
gateway.UserName = ms.ReadASIIString(20);
|
|
gateway.Password = ms.ReadASIIString(20);
|
|
gateway.DeviceCount = ms.ReadByte();
|
|
gateway.GroupCount = ms.ReadByte();
|
|
gateway.TimerCount = ms.ReadByte();
|
|
gateway.SceneCount = ms.ReadByte();
|
|
gateway.TaskCount = ms.ReadByte();
|
|
var hex = ms.ReadHexString(5);
|
|
gateway.CompileVersion = ms.ReadHexString(5);
|
|
}
|
|
gatewayRepo.SaveChanges();
|
|
}
|
|
}
|
|
}
|
|
|
|
//0x9e
|
|
//0x9f
|
|
//0xa0
|
|
//0xa1
|
|
//0xa2
|
|
//0xa3
|
|
//0xa4
|
|
//0xa5
|
|
//0xa8
|
|
//0xa9
|
|
//0xab
|
|
//0xa7
|
|
//0xac
|
|
//0xaf
|
|
//0xb0
|
|
/// <summary>
|
|
/// 0x70设备上报信息
|
|
/// </summary>
|
|
/// <param name="sn"></param>
|
|
/// <param name="data"></param>
|
|
private void X70(string sn, byte[] data)
|
|
{
|
|
using (var ms = new MemoryStream(data))
|
|
{
|
|
var responseType = ms.ReadByte();
|
|
var dataLength = ms.ReadByte();
|
|
var address = ms.ReadHexString(2);
|
|
var endpoint = ms.ReadByte();
|
|
using (var scope = _applicationServices.CreateScope())
|
|
{
|
|
var deviceRepo = scope.ServiceProvider.GetService<IRepository<FBeeDevice>>();
|
|
var device = deviceRepo.Table().FirstOrDefault(o => o.Sn == sn && o.Address == address);
|
|
var clusterId = ms.ReadInt();
|
|
if (device != null)
|
|
{
|
|
var reportCount = ms.ReadByte();
|
|
var props = new Dictionary<int, byte[]>();
|
|
for (int i = 0; i < reportCount; i++)
|
|
{
|
|
var propId = ms.ReadInt();
|
|
var propDataTypeValue = ms.ReadByte();
|
|
int propDataLength;
|
|
if (Enum.IsDefined(typeof(DataType), propDataTypeValue))
|
|
{
|
|
var propDataType = (DataType)propDataTypeValue;
|
|
if (propDataType == DataType.bitstring || propDataType == DataType.characterstring)
|
|
{
|
|
propDataLength = ms.ReadByte();
|
|
}
|
|
else if (propDataType == DataType.longbitstring || propDataType == DataType.longcharacterstring)
|
|
{
|
|
propDataLength = ms.ReadInt();
|
|
}
|
|
else if (propDataType == DataType.sequence || propDataType == DataType.set || propDataType == DataType.bag)
|
|
{
|
|
propDataLength = ms.ReadInt();
|
|
}
|
|
else if (propDataType == DataType.unknown)
|
|
{
|
|
propDataLength = 0;
|
|
}
|
|
else
|
|
{
|
|
try
|
|
{
|
|
propDataLength = Convert.ToInt32(Regex.Match(propDataType.GetName(), @"(\d+)$").Groups[1].Value);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Console.WriteLine(ex.ToString());
|
|
propDataLength = 1;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
propDataLength = 1;
|
|
}
|
|
var propData = ms.Read(propDataLength);
|
|
props.Add(propId, propData);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//0x72
|
|
//0xb1
|
|
//0xb2
|
|
//0xc1
|
|
//0xc2
|
|
//0xc3
|
|
//0xc4
|
|
//0xc5
|
|
//0x75
|
|
|
|
#endregion api
|
|
|
|
private void CheckConnection()
|
|
{
|
|
var ips = NetworkInterface.GetAllNetworkInterfaces()
|
|
.Where(nic => nic.OperationalStatus == OperationalStatus.Up && nic.NetworkInterfaceType != NetworkInterfaceType.Loopback)
|
|
.Select(nic => nic.GetIPProperties().UnicastAddresses)
|
|
.SelectMany(o => o.ToList())
|
|
.Select(o => o.Address)
|
|
.Where(o => o.AddressFamily == AddressFamily.InterNetwork)
|
|
.ToList();
|
|
var list = new ConcurrentBag<string>();
|
|
foreach (var ip in ips)
|
|
{
|
|
Console.WriteLine($"search:{ip}");
|
|
var tokenSource = new CancellationTokenSource();
|
|
using (var client = new UdpClient(new IPEndPoint(ip, 0)))
|
|
{
|
|
var message = Encoding.ASCII.GetBytes("GETIP\r\n");
|
|
client.Send(message, message.Length, new IPEndPoint(IPAddress.Parse("255.255.255.255"), 9090));
|
|
Task.Run(() =>
|
|
{
|
|
try
|
|
{
|
|
var ep = new IPEndPoint(IPAddress.Any, 3702);
|
|
while (!tokenSource.IsCancellationRequested)
|
|
{
|
|
if (client.Available > 0)
|
|
{
|
|
var buffer = client.Receive(ref ep);
|
|
var result = Encoding.ASCII.GetString(buffer);
|
|
Console.WriteLine(result);
|
|
if (!list.Any(o => o == result))
|
|
{
|
|
list.Add(result);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Console.WriteLine(ex.Message);
|
|
}
|
|
}, tokenSource.Token);
|
|
Thread.Sleep(1000);
|
|
tokenSource.Cancel();
|
|
}
|
|
}
|
|
using (var scope = _applicationServices.CreateScope())
|
|
{
|
|
var repo = scope.ServiceProvider.GetService<IRepository<Gateway>>();
|
|
foreach (var result in list)
|
|
{
|
|
var sn = Regex.Match(result, @"SN:([^\s]*)").Groups[1].Value;
|
|
var ip = Regex.Match(result, @"IP:([^\s]*)").Groups[1].Value;
|
|
var gateway = repo.Table().FirstOrDefault(o => o.Sn == sn);
|
|
if (gateway == null)
|
|
{
|
|
gateway = new Gateway { Sn = sn, Ip = ip, Enable = true };
|
|
repo.Add(gateway);
|
|
repo.SaveChanges();
|
|
}
|
|
else
|
|
{
|
|
if (gateway.Ip != ip)
|
|
{
|
|
gateway.Ip = ip;
|
|
repo.Add(gateway);
|
|
}
|
|
}
|
|
}
|
|
var gateways = repo.ReadOnlyTable().ToList();
|
|
foreach (var gateway in gateways)
|
|
{
|
|
if (gateway.Enable)
|
|
{
|
|
if (Clients.Any(o => o.Key == gateway.Sn))
|
|
{
|
|
Clients.TryGetValue(gateway.Sn, out TcpClientWrapper client);
|
|
if (client.Ip != gateway.Ip)
|
|
{
|
|
this.Connect(client);
|
|
}
|
|
else
|
|
{
|
|
if (!client.Client.Connected)
|
|
{
|
|
this.Connect(client);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
var client = new TcpClientWrapper { Sn = gateway.Sn, Ip = gateway.Ip, Client = new TcpClient() };
|
|
Clients.TryAdd(gateway.Sn, client);
|
|
this.Connect(client);
|
|
}
|
|
this.X81(gateway.Sn);
|
|
}
|
|
else
|
|
{
|
|
if (Clients.Any(o => o.Key == gateway.Sn))
|
|
{
|
|
Clients.TryRemove(gateway.Sn, out TcpClientWrapper client);
|
|
if (client.Client.Connected)
|
|
{
|
|
client.Client.Close();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private void Connect(TcpClientWrapper client)
|
|
{
|
|
try
|
|
{
|
|
if (client != null)
|
|
{
|
|
client.Client.Dispose();
|
|
client.Client = new TcpClient();
|
|
}
|
|
Console.WriteLine($"connect {client.Ip} for {client.Sn}");
|
|
client.Client.Connect(client.Ip, 8001);
|
|
new Thread(() =>
|
|
{
|
|
var stream = client.Client.GetStream();
|
|
while (client.Client.Connected)
|
|
{
|
|
if (stream.DataAvailable)
|
|
{
|
|
try
|
|
{
|
|
var buffer = new byte[512];
|
|
var length = stream.Read(buffer);
|
|
var data = buffer.ToList().Take(length).ToArray();
|
|
Console.WriteLine($"response:{BitConverter.ToString(data)}");
|
|
this.Handle(client.Sn, data);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
ex.PrintStack("read stream error");
|
|
}
|
|
}
|
|
}
|
|
}).Start();
|
|
this.X9d(client.Sn);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
ex.PrintStack();
|
|
}
|
|
}
|
|
|
|
private void Handle(string sn, byte[] data)
|
|
{
|
|
var length = 2 + data[1];
|
|
if (data.Length > length)
|
|
{
|
|
Handle(sn, data.Skip(length).ToArray());
|
|
}
|
|
else
|
|
{
|
|
this.HandleInternal(sn, data.Take(length).ToArray());
|
|
}
|
|
}
|
|
|
|
private void HandleInternal(string sn, byte[] data)
|
|
{
|
|
Console.WriteLine($"read:{BitConverter.ToString(data).Replace("-", " ")}");
|
|
var responseType = data[0];
|
|
if (responseType == ResponseType.x15)
|
|
{
|
|
this.X15(sn, data);
|
|
}
|
|
else if (responseType == ResponseType.x01)
|
|
{
|
|
this.X01(sn, data);
|
|
}
|
|
else if (responseType == ResponseType.x07)
|
|
{
|
|
this.X07(sn, data);
|
|
}
|
|
else if (responseType == ResponseType.x70)
|
|
{
|
|
this.X70(sn, data);
|
|
}
|
|
else if (responseType == ResponseType.x72)
|
|
{
|
|
//this.X70(sn, data);
|
|
}
|
|
else
|
|
{
|
|
Console.WriteLine($"{responseType} hasn't handle");
|
|
}
|
|
}
|
|
|
|
private void Write(string sn, byte commandType, List<byte> command)
|
|
{
|
|
this.Clients.TryGetValue(sn, out TcpClientWrapper client);
|
|
if (!client.Client.Connected)
|
|
{
|
|
this.Connect(client);
|
|
}
|
|
if (command == null)
|
|
{
|
|
command = new List<byte>();
|
|
}
|
|
|
|
var data = new List<byte>();
|
|
data.AddRange(sn.HexToBytes().Reverse());
|
|
data.Add(RequestType.xfe);
|
|
data.Add(commandType);
|
|
data.AddRange(command);
|
|
|
|
var head = BitConverter.GetBytes(data.Count() + 2).ToList();
|
|
if (BitConverter.IsLittleEndian)
|
|
{
|
|
head.Reverse();
|
|
}
|
|
head = head.Skip(2).Reverse().ToList();
|
|
var list = new List<byte>();
|
|
list.AddRange(head);
|
|
list.AddRange(data);
|
|
var bytes = list.ToArray();
|
|
Console.WriteLine($"write:{BitConverter.ToString(bytes).Replace("-", " ")}");
|
|
client.Client.GetStream().Write(bytes);
|
|
}
|
|
|
|
private NotifyModel CreateModel(string name, string number, string path, string icon)
|
|
{
|
|
var host = string.IsNullOrEmpty(this._configuration["server.ip"]) ? "localhost" : this._configuration["server.ip"];
|
|
var port = Convert.ToInt32(Regex.Match(this._configuration["server.urls"], @"(?<=:)\d+").Value);
|
|
|
|
return new NotifyModel
|
|
{
|
|
CategoryName = "电器",
|
|
CategoryNumber = "20",
|
|
Name = name,
|
|
Number = number,
|
|
Icon = icon,
|
|
IsOnline = true,
|
|
BaseUrl = $"http://{host}:{port}/{path}",
|
|
ApiPath = "/api"
|
|
};
|
|
}
|
|
|
|
private void NotifyServer(NotifyModel model)
|
|
{
|
|
var url = $"http://{this._configuration["node.url"]}/Notify";
|
|
Console.WriteLine(url);
|
|
var hc = this._httpClientFactory.CreateClient();
|
|
var task = this._httpClientFactory.CreateClient().PostAsync(url, new FormUrlEncodedContent(model.ToList()));
|
|
task.Wait();
|
|
using (var response = task.Result)
|
|
{
|
|
using (var content = response.Content)
|
|
{
|
|
var value = content.ReadAsStringAsync().Result;
|
|
Console.WriteLine($"end:{url}:{value}");
|
|
}
|
|
}
|
|
}
|
|
|
|
public void Dispose()
|
|
{
|
|
Console.WriteLine("dispose...");
|
|
this._tokenSource.Cancel();
|
|
foreach (var item in Clients)
|
|
{
|
|
if (item.Value.Client != null)
|
|
{
|
|
item.Value.Client.Dispose();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
} |