CustomUnnamedMessageHandler.cs 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. using UnityEngine;
  2. using Unity.Collections;
  3. using Unity.Netcode;
  4. //自定义的Unnamed消息处理。结构跟普通差不多,只是用来处理自定义的数据,而不是NetCode规定的NetworkVariable
  5. public class UnnamedStringMessageHandler : CustomUnnamedMessageHandler<string>
  6. {
  7. //定义唯一的消息ID,作为消息头,可以用其他方式构建消息id
  8. protected override byte MessageType()
  9. {
  10. return 1;
  11. }
  12. public override void OnNetworkSpawn()
  13. {
  14. base.OnNetworkSpawn();
  15. if(IsServer)
  16. {
  17. NetworkManager.OnClientConnectedCallback += OnClientConnectedCallback;
  18. }
  19. else
  20. {
  21. //客户端,给服务器发消息
  22. SendUnnamedMessage("I am a client connecting!");
  23. }
  24. }
  25. public override void OnNetworkDespawn()
  26. {
  27. base.OnNetworkDespawn();
  28. NetworkManager.OnClientConnectedCallback -= OnClientConnectedCallback;
  29. }
  30. //其他客户端连接上来,通知所有客户端
  31. private void OnClientConnectedCallback(ulong clientId)
  32. {
  33. SendUnnamedMessage($"welcome the newly joined client ({clientId})!");
  34. }
  35. //解析消息
  36. protected override void OnReceivedUnnamedMessage(ulong clientId, FastBufferReader reader)
  37. {
  38. var stringMessage = string.Empty;
  39. reader.ReadValueSafe(out stringMessage);
  40. if(IsServer)
  41. {
  42. Debug.Log($"Server received unnamed message of type ({MessageType()}) from client " +
  43. $"({clientId}) that contained the string: \"{stringMessage}\"");
  44. //可以通知所有客户端
  45. SendUnnamedMessage($"Newly connected client sent this greeting: \"{stringMessage}\"");
  46. }
  47. else
  48. {
  49. Debug.Log(stringMessage);
  50. }
  51. }
  52. //发送数据(payload)
  53. public override void SendUnnamedMessage(string dataToSend)
  54. {
  55. var writer = new FastBufferWriter(1100, Allocator.Temp);
  56. var customMessagingManager = NetworkManager.CustomMessagingManager;
  57. using(writer)
  58. {
  59. //写入消息头
  60. writer.WriteValueSafe(MessageType());
  61. //写入消息体
  62. writer.WriteValueSafe(dataToSend);
  63. if(IsServer)
  64. {
  65. //发送消息,SendUnnamedMessageToAll方法只能Server调用,Client调用会报异常
  66. customMessagingManager.SendUnnamedMessageToAll(writer);
  67. }
  68. else
  69. {
  70. //发送给服务器。SendUnnamedMessage方法可以Client和Server之间互相调用发送
  71. //NetworkManager.ServerClientId表示服务器的id。为了保持一致性,服务端也要有一个ClientID,便于客户端向服务端发送消息。默认为0,不能更改。
  72. //感觉取名ServerId会更好?
  73. customMessagingManager.SendUnnamedMessage(NetworkManager.ServerClientId, writer);
  74. }
  75. }
  76. }
  77. }
  78. //消息处理基类,必须继承NetworkBehaviour。T是要发送的消息类型
  79. public class CustomUnnamedMessageHandler<T> : NetworkBehaviour
  80. {
  81. protected virtual byte MessageType()
  82. {
  83. return 0;
  84. }
  85. public override void OnNetworkSpawn()
  86. {
  87. //三种模式都要订阅
  88. NetworkManager.CustomMessagingManager.OnUnnamedMessage += ReceiveMessage;
  89. }
  90. public override void OnNetworkDespawn()
  91. {
  92. NetworkManager.CustomMessagingManager.OnUnnamedMessage -= ReceiveMessage;
  93. }
  94. //自定义处理,可以进行消息解析,并处理
  95. protected virtual void OnReceivedUnnamedMessage(ulong clientId, FastBufferReader reader)
  96. {
  97. }
  98. //处理收到的消息数据
  99. private void ReceiveMessage(ulong clientId, FastBufferReader reader)
  100. {
  101. //判断消息类型
  102. var messageType = (byte)0;
  103. reader.ReadValueSafe(out messageType);
  104. //解析消息
  105. if(messageType == MessageType())
  106. {
  107. OnReceivedUnnamedMessage(clientId, reader);
  108. }
  109. }
  110. //发送消息
  111. public virtual void SendUnnamedMessage(T dataToSend)
  112. {
  113. }
  114. }