BleUDP.cs 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. using System;
  5. using System.Net;
  6. using System.Net.Sockets;
  7. using System.Text;
  8. using System.Threading;
  9. public class BleUDP : MonoBehaviour
  10. {
  11. public static BleUDP ins; //单例记录
  12. readonly string localIP = "127.0.0.1"; //本地IP
  13. readonly int myPort = 8001; //自身的注册端口
  14. readonly int targetPort = 8000; //发消息的目标端口
  15. Socket client; //UDP对象
  16. float noneMsgTime = 0; //多久没收到字节消息了
  17. Queue<byte[]> byteQueue = new Queue<byte[]>(); //接收信息的线程把字节信息放这里
  18. Queue<byte[]> byteMainQueue = new Queue<byte[]>(); //主线程从byteQueue中取出数据后放在这里,供主线程update使用
  19. public Action OnConnected;
  20. public Action OnConnectionFailed;
  21. public Action<byte[]> OnCharacteristicChanged;
  22. public Action OnScanEnded;
  23. [NonSerialized] public BluetoothStatusEnum bluetoothStatusEnum = BluetoothStatusEnum.Connect;
  24. void Awake()
  25. {
  26. if (ins)
  27. {
  28. Destroy(this.gameObject);
  29. return;
  30. }
  31. ins = this;
  32. DontDestroyOnLoad(this.gameObject);
  33. client = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
  34. client.Bind(new IPEndPoint(IPAddress.Parse(localIP), myPort));
  35. Thread threadReciveMsg = new Thread(ReciveMsg);
  36. threadReciveMsg.Start();
  37. }
  38. void OnDestroy()
  39. {
  40. if (ins == this) ins = null;
  41. client.Close();
  42. }
  43. void Update()
  44. {
  45. lock (byteQueue)
  46. {
  47. while (byteQueue.Count > 0)
  48. {
  49. byteMainQueue.Enqueue(byteQueue.Dequeue());
  50. }
  51. }
  52. if (bluetoothStatusEnum == BluetoothStatusEnum.Connecting)
  53. {
  54. if (noneMsgTime > 5)
  55. {
  56. bluetoothStatusEnum = BluetoothStatusEnum.ConnectFail;
  57. EmitOnConnectionFailed();
  58. return;
  59. }
  60. else if (byteMainQueue.Count > 0)
  61. {
  62. bluetoothStatusEnum = BluetoothStatusEnum.ConnectSuccess;
  63. EmitOnConnected();
  64. }
  65. }
  66. else if (bluetoothStatusEnum == BluetoothStatusEnum.ConnectSuccess)
  67. {
  68. if (noneMsgTime > 5)
  69. {
  70. bluetoothStatusEnum = BluetoothStatusEnum.ConnectFail;
  71. EmitOnConnectionFailed();
  72. }
  73. }
  74. else
  75. {
  76. byteMainQueue.Clear();
  77. return;
  78. }
  79. if (byteMainQueue.Count == 0)
  80. {
  81. noneMsgTime += Time.deltaTime;
  82. return;
  83. }
  84. noneMsgTime = 0;
  85. while (byteMainQueue.Count > 0)
  86. {
  87. EmitOnCharacteristicChanged(byteMainQueue.Dequeue());
  88. }
  89. }
  90. public void SendMsg(string data)
  91. {
  92. Debug.LogWarning("sendMsgToBle: " + data);
  93. EndPoint point = new IPEndPoint(IPAddress.Parse(localIP), targetPort);
  94. client.SendTo(Encoding.UTF8.GetBytes(data), point);
  95. }
  96. void ReciveMsg()
  97. {
  98. while (true)
  99. {
  100. EndPoint point = new IPEndPoint(IPAddress.Any, 0);
  101. byte[] buffer = new byte[1024];
  102. int length = client.ReceiveFrom(buffer, ref point);
  103. if (!point.ToString().EndsWith(targetPort.ToString())) return;
  104. if (length <= 0) continue;
  105. byte[] bytes = new byte[length];
  106. Array.Copy(buffer, bytes, length);
  107. lock (byteQueue)
  108. {
  109. byteQueue.Enqueue(bytes);
  110. }
  111. }
  112. }
  113. public void ScanNearbyDevices()
  114. {
  115. EmitOnScanEnded();
  116. }
  117. public void Connect()
  118. {
  119. noneMsgTime = 0;
  120. bluetoothStatusEnum = BluetoothStatusEnum.Connecting;
  121. SendMsg("V");
  122. }
  123. public void Disconnect()
  124. {
  125. bluetoothStatusEnum = BluetoothStatusEnum.Connect;
  126. }
  127. void EmitOnConnected()
  128. {
  129. try
  130. {
  131. OnConnected?.Invoke();
  132. }
  133. catch (Exception) { }
  134. }
  135. void EmitOnConnectionFailed()
  136. {
  137. try
  138. {
  139. OnConnectionFailed?.Invoke();
  140. }
  141. catch (Exception) { }
  142. }
  143. void EmitOnCharacteristicChanged(byte[] bytes)
  144. {
  145. try
  146. {
  147. OnCharacteristicChanged?.Invoke(bytes);
  148. }
  149. catch (Exception) { }
  150. }
  151. void EmitOnScanEnded()
  152. {
  153. try
  154. {
  155. OnScanEnded?.Invoke();
  156. }
  157. catch (Exception) { }
  158. }
  159. }