LocalServerSearcher.cs 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. /****************************************************************************
  2. * Copyright 2019 Nreal Techonology Limited. All rights reserved.
  3. *
  4. * This file is part of NRSDK.
  5. *
  6. * https://www.nreal.ai/
  7. *
  8. *****************************************************************************/
  9. namespace NRKernal.Experimental.NetWork
  10. {
  11. using System;
  12. using System.Collections;
  13. using System.Collections.Generic;
  14. using System.Net;
  15. using System.Net.Sockets;
  16. using System.Text;
  17. using System.Threading;
  18. using UnityEngine;
  19. public class LocalServerSearcher : SingleTon<LocalServerSearcher>
  20. {
  21. public struct ServerInfoResult
  22. {
  23. public bool isSuccess;
  24. public IPEndPoint endPoint;
  25. }
  26. public delegate void OnGetSearchResult(ServerInfoResult result);
  27. private UdpClient client;
  28. private IPEndPoint endpoint;
  29. Thread m_ReceiveThread = null;
  30. private const string SEARCHSERVERIP = "FIND-SERVER";
  31. private const int BroadCastPort = 6001;
  32. private static float TimeoutWaittingTime = 3f;
  33. private IPEndPoint m_LocalServer;
  34. private Queue<OnGetSearchResult> m_Tasks = new Queue<OnGetSearchResult>();
  35. private Coroutine m_TimeOutCoroutine = null;
  36. public LocalServerSearcher()
  37. {
  38. client = new UdpClient(new IPEndPoint(IPAddress.Any, 0));
  39. endpoint = new IPEndPoint(IPAddress.Parse("255.255.255.255"), BroadCastPort);
  40. MainThreadDispather.Initialize();
  41. }
  42. public void Search(OnGetSearchResult callback)
  43. {
  44. lock (m_Tasks)
  45. {
  46. m_Tasks.Enqueue(callback);
  47. }
  48. if (m_ReceiveThread == null)
  49. {
  50. m_ReceiveThread = new Thread(new ThreadStart(RecvThread));
  51. m_ReceiveThread.IsBackground = true;
  52. m_ReceiveThread.Start();
  53. }
  54. RequestForServerIP();
  55. if (m_TimeOutCoroutine != null)
  56. {
  57. NRKernalUpdater.Instance.StopCoroutine(m_TimeOutCoroutine);
  58. m_TimeOutCoroutine = null;
  59. }
  60. m_TimeOutCoroutine = NRKernalUpdater.Instance.StartCoroutine(TimeOut());
  61. }
  62. private void RequestForServerIP()
  63. {
  64. byte[] buf = Encoding.Default.GetBytes(SEARCHSERVERIP);
  65. client.Send(buf, buf.Length, endpoint);
  66. }
  67. private void RecvThread()
  68. {
  69. IPEndPoint endpoint = new IPEndPoint(IPAddress.Any, BroadCastPort);
  70. while (true)
  71. {
  72. try
  73. {
  74. byte[] buf = client.Receive(ref endpoint);
  75. string data = Encoding.Default.GetString(buf);
  76. NRDebugger.Info("[LocalServerSearcher] Get the server info:" + data);
  77. if (!string.IsNullOrEmpty(data))
  78. {
  79. string[] param = data.Split(':');
  80. if (param != null && param.Length == 2)
  81. {
  82. m_LocalServer = new IPEndPoint(IPAddress.Parse(param[0]), int.Parse(param[1]));
  83. Response(m_LocalServer);
  84. }
  85. }
  86. }
  87. catch (Exception e)
  88. {
  89. throw e;
  90. }
  91. }
  92. }
  93. private IEnumerator TimeOut()
  94. {
  95. float time_last = 0f;
  96. while (true)
  97. {
  98. yield return new WaitForEndOfFrame();
  99. time_last += Time.deltaTime;
  100. if (time_last > TimeoutWaittingTime)
  101. {
  102. Response(null);
  103. }
  104. }
  105. }
  106. private void Response(IPEndPoint endpoint)
  107. {
  108. if (m_Tasks.Count == 0)
  109. {
  110. return;
  111. }
  112. MainThreadDispather.QueueOnMainThread(() =>
  113. {
  114. ServerInfoResult result = new ServerInfoResult();
  115. result.endPoint = endpoint;
  116. result.isSuccess = endpoint != null;
  117. lock (m_Tasks)
  118. {
  119. if (m_Tasks.Count == 0)
  120. {
  121. return;
  122. }
  123. var callback = m_Tasks.Dequeue();
  124. while (callback != null)
  125. {
  126. try
  127. {
  128. callback?.Invoke(result);
  129. }
  130. catch (Exception e)
  131. {
  132. throw e;
  133. }
  134. if (m_Tasks.Count == 0)
  135. {
  136. return;
  137. }
  138. callback = m_Tasks.Dequeue();
  139. }
  140. }
  141. });
  142. }
  143. }
  144. }