DeviceDiscovery.cs 3.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. using IDeviceDiscovery;
  2. using Shaker.Model;
  3. using Shaker.Models;
  4. using Shaker.Tools;
  5. using System;
  6. using System.Collections.Generic;
  7. using System.Diagnostics.CodeAnalysis;
  8. using System.Linq;
  9. using System.Net;
  10. using System.Text;
  11. using System.Threading.Tasks;
  12. namespace DeviceDiscovery
  13. {
  14. internal class DeviceDiscovery : IDeviceDiscovery.IDeviceDiscovery
  15. {
  16. [AllowNull]
  17. private CancellationTokenSource deviceDiscoveryTokenSource;
  18. public int DiscoveryPort { get; private set; }
  19. [AllowNull]
  20. public string MulticastGroup { get; private set; }
  21. [AllowNull]
  22. public Func<SearchDeviceModel, ResultDeviceModel> OnDeviceFound { get; set; }
  23. public bool IsStart { get; private set; }
  24. public void Init(int discoveryPort = 16656, string multicastGroup = "239.1.0.3")
  25. {
  26. DiscoveryPort = discoveryPort;
  27. MulticastGroup = multicastGroup;
  28. }
  29. private void Log(string message)
  30. {
  31. EventBus.EventBroker.Instance.GetEvent(Shaker.Model.Topic.LOG).Publish(this, null, message);
  32. }
  33. public void Start()
  34. {
  35. Task.Run(async () =>
  36. {
  37. System.Net.Sockets.UdpClient udpClient = new System.Net.Sockets.UdpClient(Topic.DISCOVERYPORT);
  38. udpClient.JoinMulticastGroup(IPAddress.Parse(Topic.MulticastGroup));
  39. Log("网络发现服务启动");
  40. deviceDiscoveryTokenSource = new CancellationTokenSource();
  41. IsStart = true;
  42. while (!deviceDiscoveryTokenSource.IsCancellationRequested)
  43. {
  44. var result = await udpClient.ReceiveAsync(deviceDiscoveryTokenSource.Token);
  45. if (OnDeviceFound == null) continue;
  46. try
  47. {
  48. var msg = result.Buffer.GetValue<SearchDeviceModel>();
  49. if (msg != null)
  50. {
  51. Log($"{result.RemoteEndPoint.Address}开始扫描");
  52. var networks = System.Net.NetworkInformation.NetworkInterface.GetAllNetworkInterfaces();
  53. var aa = networks.Where(x => x.OperationalStatus == System.Net.NetworkInformation.OperationalStatus.Up).Select(x => x.GetIPProperties().UnicastAddresses).SelectMany(x => x).Where(x => x.Address.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork).ToList();
  54. int index = aa.FindIndex(x =>
  55. {
  56. return (BitConverter.ToUInt32(x.Address.GetAddressBytes(), 0) & BitConverter.ToUInt32(x.IPv4Mask.GetAddressBytes(), 0)) == (BitConverter.ToUInt32(result.RemoteEndPoint.Address.GetAddressBytes()) & BitConverter.ToUInt32(x.IPv4Mask.GetAddressBytes()));
  57. });
  58. ResultDeviceModel resultDevice = OnDeviceFound(msg);
  59. resultDevice ??= new ResultDeviceModel();
  60. if (index == -1)
  61. {
  62. resultDevice.DeviceInfoModel.IP = "127.0.0.1";
  63. }
  64. else
  65. {
  66. resultDevice.DeviceInfoModel.IP = aa[index].Address.ToString();
  67. }
  68. Log($"返回地址{resultDevice.DeviceInfoModel.IP}:{resultDevice.DeviceInfoModel.Port}");
  69. udpClient.Send(resultDevice.GetBytes(), new System.Net.IPEndPoint(IPAddress.Broadcast, Topic.DISCOVERYPORT - 1));
  70. }
  71. }
  72. catch
  73. { }
  74. }
  75. udpClient.Close();
  76. });
  77. }
  78. public void Stop()
  79. {
  80. deviceDiscoveryTokenSource?.Cancel();
  81. IsStart = false;
  82. }
  83. }
  84. }