From bd7c225eb76345b96c79faedfb50d1dc1852d5c3 Mon Sep 17 00:00:00 2001 From: zaddo67 Date: Thu, 24 Dec 2020 06:54:02 +1000 Subject: [PATCH 1/6] Save rubbish --- ...CoreApp,Version=v3.0.AssemblyAttributes.cs | 4 ++++ .../ForgeNatHolePunch.AssemblyInfo.cs | 23 +++++++++++++++++++ ...CoreApp,Version=v3.0.AssemblyAttributes.cs | 4 ++++ .../ForgeSampleGameServer.AssemblyInfo.cs | 23 +++++++++++++++++++ ...CoreApp,Version=v3.0.AssemblyAttributes.cs | 4 ++++ ...ForgeServerRegistryService.AssemblyInfo.cs | 23 +++++++++++++++++++ 6 files changed, 81 insertions(+) create mode 100644 ForgeAlloy/ForgeNatHolePunch/obj/Release/netcoreapp3.0/.NETCoreApp,Version=v3.0.AssemblyAttributes.cs create mode 100644 ForgeAlloy/ForgeNatHolePunch/obj/Release/netcoreapp3.0/ForgeNatHolePunch.AssemblyInfo.cs create mode 100644 ForgeAlloy/ForgeSampleGameServer/obj/Release/netcoreapp3.0/.NETCoreApp,Version=v3.0.AssemblyAttributes.cs create mode 100644 ForgeAlloy/ForgeSampleGameServer/obj/Release/netcoreapp3.0/ForgeSampleGameServer.AssemblyInfo.cs create mode 100644 ForgeAlloy/ForgeServerRegistryService/obj/Release/netcoreapp3.0/.NETCoreApp,Version=v3.0.AssemblyAttributes.cs create mode 100644 ForgeAlloy/ForgeServerRegistryService/obj/Release/netcoreapp3.0/ForgeServerRegistryService.AssemblyInfo.cs diff --git a/ForgeAlloy/ForgeNatHolePunch/obj/Release/netcoreapp3.0/.NETCoreApp,Version=v3.0.AssemblyAttributes.cs b/ForgeAlloy/ForgeNatHolePunch/obj/Release/netcoreapp3.0/.NETCoreApp,Version=v3.0.AssemblyAttributes.cs new file mode 100644 index 00000000..cc083fe5 --- /dev/null +++ b/ForgeAlloy/ForgeNatHolePunch/obj/Release/netcoreapp3.0/.NETCoreApp,Version=v3.0.AssemblyAttributes.cs @@ -0,0 +1,4 @@ +// +using System; +using System.Reflection; +[assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute(".NETCoreApp,Version=v3.0", FrameworkDisplayName = "")] diff --git a/ForgeAlloy/ForgeNatHolePunch/obj/Release/netcoreapp3.0/ForgeNatHolePunch.AssemblyInfo.cs b/ForgeAlloy/ForgeNatHolePunch/obj/Release/netcoreapp3.0/ForgeNatHolePunch.AssemblyInfo.cs new file mode 100644 index 00000000..8caeb7d8 --- /dev/null +++ b/ForgeAlloy/ForgeNatHolePunch/obj/Release/netcoreapp3.0/ForgeNatHolePunch.AssemblyInfo.cs @@ -0,0 +1,23 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +using System; +using System.Reflection; + +[assembly: System.Reflection.AssemblyCompanyAttribute("ForgeNatHolePunch")] +[assembly: System.Reflection.AssemblyConfigurationAttribute("Release")] +[assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")] +[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0")] +[assembly: System.Reflection.AssemblyProductAttribute("ForgeNatHolePunch")] +[assembly: System.Reflection.AssemblyTitleAttribute("ForgeNatHolePunch")] +[assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")] + +// Generated by the MSBuild WriteCodeFragment class. + diff --git a/ForgeAlloy/ForgeSampleGameServer/obj/Release/netcoreapp3.0/.NETCoreApp,Version=v3.0.AssemblyAttributes.cs b/ForgeAlloy/ForgeSampleGameServer/obj/Release/netcoreapp3.0/.NETCoreApp,Version=v3.0.AssemblyAttributes.cs new file mode 100644 index 00000000..cc083fe5 --- /dev/null +++ b/ForgeAlloy/ForgeSampleGameServer/obj/Release/netcoreapp3.0/.NETCoreApp,Version=v3.0.AssemblyAttributes.cs @@ -0,0 +1,4 @@ +// +using System; +using System.Reflection; +[assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute(".NETCoreApp,Version=v3.0", FrameworkDisplayName = "")] diff --git a/ForgeAlloy/ForgeSampleGameServer/obj/Release/netcoreapp3.0/ForgeSampleGameServer.AssemblyInfo.cs b/ForgeAlloy/ForgeSampleGameServer/obj/Release/netcoreapp3.0/ForgeSampleGameServer.AssemblyInfo.cs new file mode 100644 index 00000000..0fc20923 --- /dev/null +++ b/ForgeAlloy/ForgeSampleGameServer/obj/Release/netcoreapp3.0/ForgeSampleGameServer.AssemblyInfo.cs @@ -0,0 +1,23 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +using System; +using System.Reflection; + +[assembly: System.Reflection.AssemblyCompanyAttribute("ForgeSampleGameServer")] +[assembly: System.Reflection.AssemblyConfigurationAttribute("Release")] +[assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")] +[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0")] +[assembly: System.Reflection.AssemblyProductAttribute("ForgeSampleGameServer")] +[assembly: System.Reflection.AssemblyTitleAttribute("ForgeSampleGameServer")] +[assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")] + +// Generated by the MSBuild WriteCodeFragment class. + diff --git a/ForgeAlloy/ForgeServerRegistryService/obj/Release/netcoreapp3.0/.NETCoreApp,Version=v3.0.AssemblyAttributes.cs b/ForgeAlloy/ForgeServerRegistryService/obj/Release/netcoreapp3.0/.NETCoreApp,Version=v3.0.AssemblyAttributes.cs new file mode 100644 index 00000000..cc083fe5 --- /dev/null +++ b/ForgeAlloy/ForgeServerRegistryService/obj/Release/netcoreapp3.0/.NETCoreApp,Version=v3.0.AssemblyAttributes.cs @@ -0,0 +1,4 @@ +// +using System; +using System.Reflection; +[assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute(".NETCoreApp,Version=v3.0", FrameworkDisplayName = "")] diff --git a/ForgeAlloy/ForgeServerRegistryService/obj/Release/netcoreapp3.0/ForgeServerRegistryService.AssemblyInfo.cs b/ForgeAlloy/ForgeServerRegistryService/obj/Release/netcoreapp3.0/ForgeServerRegistryService.AssemblyInfo.cs new file mode 100644 index 00000000..12f437a2 --- /dev/null +++ b/ForgeAlloy/ForgeServerRegistryService/obj/Release/netcoreapp3.0/ForgeServerRegistryService.AssemblyInfo.cs @@ -0,0 +1,23 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +using System; +using System.Reflection; + +[assembly: System.Reflection.AssemblyCompanyAttribute("ForgeServerRegistryService")] +[assembly: System.Reflection.AssemblyConfigurationAttribute("Release")] +[assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")] +[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0")] +[assembly: System.Reflection.AssemblyProductAttribute("ForgeServerRegistryService")] +[assembly: System.Reflection.AssemblyTitleAttribute("ForgeServerRegistryService")] +[assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")] + +// Generated by the MSBuild WriteCodeFragment class. + From 44cf2172611b2c60312667b57860e3f9ee0e12ce Mon Sep 17 00:00:00 2001 From: zaddo67 Date: Thu, 24 Dec 2020 06:58:53 +1000 Subject: [PATCH 2/6] Prevent PlayerRepository duplicate error Make BMSBytePool thread safe --- .../Sockets/ForgeUDPSocketServerFacade.cs | 50 +++++++++++++------ .../Serialization/BMSBytePool.cs | 42 ++++++++++------ 2 files changed, 63 insertions(+), 29 deletions(-) diff --git a/ForgeAlloy/ForgeAlloyUnity/Assets/ForgeNetworking/Networking/Sockets/ForgeUDPSocketServerFacade.cs b/ForgeAlloy/ForgeAlloyUnity/Assets/ForgeNetworking/Networking/Sockets/ForgeUDPSocketServerFacade.cs index 59df53d8..36b1a6e4 100644 --- a/ForgeAlloy/ForgeAlloyUnity/Assets/ForgeNetworking/Networking/Sockets/ForgeUDPSocketServerFacade.cs +++ b/ForgeAlloy/ForgeAlloyUnity/Assets/ForgeNetworking/Networking/Sockets/ForgeUDPSocketServerFacade.cs @@ -45,21 +45,28 @@ public override void ShutDown() base.ShutDown(); } - public void ChallengeSuccess(INetworkMediator netContainer, EndPoint endpoint) + public void ChallengeSuccess(INetworkMediator netContainer, EndPoint endpoint) { INetPlayer player; - ForgeNetworkIdentityMessage netIdentity; + ForgeNetworkIdentityMessage netIdentity = null; lock (_challengedPlayers) { - player = _challengedPlayers.GetPlayer(endpoint); - netContainer.PlayerRepository.AddPlayer(player); - netIdentity = new ForgeNetworkIdentityMessage + if (_challengedPlayers.Exists(endpoint)) // CHANGE: Trap mallicious client sending multiple creates { - Identity = player.Id - }; - _challengedPlayers.RemovePlayer(player); + player = _challengedPlayers.GetPlayer(endpoint); + if (!netContainer.PlayerRepository.Exists(endpoint)) // CHANGE: Check for duplicate + { + netContainer.PlayerRepository.AddPlayer(player); + netIdentity = new ForgeNetworkIdentityMessage + { + Identity = player.Id + }; + } + _challengedPlayers.RemovePlayer(player); + } } - netContainer.MessageBus.SendReliableMessage(netIdentity, ManagedSocket, endpoint); + if (netIdentity != null) + netContainer.MessageBus.SendReliableMessage(netIdentity, ManagedSocket, endpoint); } protected override void ProcessMessageRead(BMSByte buffer, EndPoint sender) @@ -83,13 +90,26 @@ protected override void ProcessMessageRead(BMSByte buffer, EndPoint sender) private void CreatePlayer(object state) { + bool sendChallenge = false; var sender = (EndPoint)state; - var newPlayer = AbstractFactory.Get().GetNew(); - newPlayer.EndPoint = sender; - newPlayer.LastCommunication = DateTime.Now; - _challengedPlayers.AddPlayer(newPlayer); - var challengeMessage = AbstractFactory.Get().GetNew(); - networkMediator.MessageBus.SendReliableMessage(challengeMessage, ManagedSocket, sender); + + lock (_challengedPlayers) // CHANGE: Need to lock because this runs on different thread + { + if (!_challengedPlayers.Exists(sender)) // CHANGE: ProcessMessageRead may run multiple times CreatePlayer and call this multiple times before the player gets created. + { + var newPlayer = AbstractFactory.Get().GetNew(); + newPlayer.EndPoint = sender; + newPlayer.LastCommunication = DateTime.Now; + _challengedPlayers.AddPlayer(newPlayer); + sendChallenge = true; + } + } + + if (sendChallenge) + { + var challengeMessage = AbstractFactory.Get().GetNew(); + networkMediator.MessageBus.SendReliableMessage(challengeMessage, ManagedSocket, sender); + } } protected void ProcessPlayerMessageRead(INetPlayer player, BMSByte buffer) diff --git a/ForgeAlloy/ForgeAlloyUnity/Assets/ForgeNetworking/Serialization/BMSBytePool.cs b/ForgeAlloy/ForgeAlloyUnity/Assets/ForgeNetworking/Serialization/BMSBytePool.cs index cb17bf10..14ea48fa 100644 --- a/ForgeAlloy/ForgeAlloyUnity/Assets/ForgeNetworking/Serialization/BMSBytePool.cs +++ b/ForgeAlloy/ForgeAlloyUnity/Assets/ForgeNetworking/Serialization/BMSBytePool.cs @@ -8,37 +8,51 @@ public class BMSBytePool private const int APPROX_SIZE_ZONE = 128; private readonly List _availableBuffers = new List(); private readonly List _inUseBuffers = new List(); + private System.Object syncLock = new object(); public BMSByte Get(int size) { - if (_availableBuffers.Count == 0) - return CreateNewBuffer(size); - else + BMSByte buff; + + lock (syncLock) { - BMSByte buff = GetAvailableBuffer(size); - if (buff.byteArr.Length < size) - buff.SetArraySize(size); - return buff; + if (_availableBuffers.Count == 0) + buff = CreateNewBuffer(size); + else + { + buff = GetAvailableBuffer(size); + if (buff.byteArr.Length < size) + buff.SetArraySize(size); + } } + return buff; } public void Release(BMSByte buffer) { // TODO: Figure out why _inUseBuffers.Remove(buffer) is returning false bool found = false; - for (int i = 0; i < _inUseBuffers.Count; i++) + + lock (syncLock) { - if (_inUseBuffers[i] == buffer) + for (int i = 0; i < _inUseBuffers.Count; i++) { - _inUseBuffers.RemoveAt(i); - found = true; - break; + if (_inUseBuffers[i] == buffer) + { + _inUseBuffers.RemoveAt(i); + found = true; + break; + } + } + if (found) + { + _availableBuffers.Add(buffer); + buffer.Clear(); } } if (!found) throw new BMSBytePoolReleaseUnmanagedBufferException(); - _availableBuffers.Add(buffer); - buffer.Clear(); + } private BMSByte GetAvailableBuffer(int size) From 9efb54276573ad6408692afb20c5551273fac131 Mon Sep 17 00:00:00 2001 From: zaddo67 Date: Thu, 31 Dec 2020 20:53:35 +1000 Subject: [PATCH 3/6] ForgeMessage Instantiate and Pool Thread Safe --- .../Networking/Messaging/ForgeMessageCodes.cs | 14 +++++++++ .../Networking/Messaging/MessagePoolMulti.cs | 29 ++++++++++++++----- 2 files changed, 35 insertions(+), 8 deletions(-) diff --git a/ForgeAlloy/ForgeAlloyUnity/Assets/ForgeNetworking/Networking/Messaging/ForgeMessageCodes.cs b/ForgeAlloy/ForgeAlloyUnity/Assets/ForgeNetworking/Networking/Messaging/ForgeMessageCodes.cs index c8afe777..a16569ce 100644 --- a/ForgeAlloy/ForgeAlloyUnity/Assets/ForgeNetworking/Networking/Messaging/ForgeMessageCodes.cs +++ b/ForgeAlloy/ForgeAlloyUnity/Assets/ForgeNetworking/Networking/Messaging/ForgeMessageCodes.cs @@ -53,6 +53,20 @@ public static int GetCodeFromType(Type type) return code; } + /// + /// Instantiate a message of Type T + /// + /// + /// var dieMsg = ForgeMessageCodes.Instantiate(); + /// + /// + /// + public static T Instantiate() + { + int code = GetCodeFromType(typeof(T)); + return (T)Instantiate(code); + } + public static void Clear() { _messageTypes.Clear(); diff --git a/ForgeAlloy/ForgeAlloyUnity/Assets/ForgeNetworking/Networking/Messaging/MessagePoolMulti.cs b/ForgeAlloy/ForgeAlloyUnity/Assets/ForgeNetworking/Networking/Messaging/MessagePoolMulti.cs index e2c7040e..3b785089 100644 --- a/ForgeAlloy/ForgeAlloyUnity/Assets/ForgeNetworking/Networking/Messaging/MessagePoolMulti.cs +++ b/ForgeAlloy/ForgeAlloyUnity/Assets/ForgeNetworking/Networking/Messaging/MessagePoolMulti.cs @@ -1,11 +1,12 @@ using System; using System.Collections.Generic; +using System.Collections.Concurrent; namespace Forge.Networking.Messaging { public class MessagePoolMulti { - private readonly Dictionary> _messagePools = new Dictionary>(); + private readonly Dictionary> _messagePools = new Dictionary>(); public IMessage Get(Type t) { @@ -13,7 +14,13 @@ public IMessage Get(Type t) if (pool.Count == 0) return CreateNewMessageForPool(t, pool); else - return pool.Dequeue(); + { + // Try to dequeue, but if locked default to create new + IMessage item; + if (pool.TryDequeue(out item)) + return item; + else return CreateNewMessageForPool(t, pool); + } } public T Get() where T : IMessage, new() @@ -22,27 +29,33 @@ public IMessage Get(Type t) if (pool.Count == 0) return CreateNewMessageForPool(pool); else - return (T)pool.Dequeue(); + { + // Try to dequeue, but if locked default to create new + IMessage item; + if (pool.TryDequeue(out item)) + return (T)item; + else return CreateNewMessageForPool(pool); + } } - private Queue GetPool(Type type) + private ConcurrentQueue GetPool(Type type) { if (!_messagePools.TryGetValue(type, out var pool)) { - pool = new Queue(); + pool = new ConcurrentQueue(); _messagePools.Add(type, pool); } return pool; } - private T CreateNewMessageForPool(Queue pool) where T : IMessage, new() + private T CreateNewMessageForPool(ConcurrentQueue pool) where T : IMessage, new() { T m = new T(); m.OnMessageSent += Release; return m; } - private IMessage CreateNewMessageForPool(Type t, Queue pool) + private IMessage CreateNewMessageForPool(Type t, ConcurrentQueue pool) { IMessage m = (IMessage)Activator.CreateInstance(t); m.OnMessageSent += Release; @@ -51,7 +64,7 @@ private IMessage CreateNewMessageForPool(Type t, Queue pool) private void Release(IMessage message) { - Queue pool = GetPool(message.GetType()); + ConcurrentQueue pool = GetPool(message.GetType()); pool.Enqueue(message); } } From 1c19c5b1c05349c9039e9b3aa892e0d6f8d87201 Mon Sep 17 00:00:00 2001 From: zaddo67 Date: Thu, 31 Dec 2020 22:46:21 +1000 Subject: [PATCH 4/6] Allow ForgeMessage to be sent multiple times --- .../ForgeNetworking/Networking/Messaging/ForgeMessage.cs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/ForgeAlloy/ForgeAlloyUnity/Assets/ForgeNetworking/Networking/Messaging/ForgeMessage.cs b/ForgeAlloy/ForgeAlloyUnity/Assets/ForgeNetworking/Networking/Messaging/ForgeMessage.cs index 84d844fc..eb177e27 100644 --- a/ForgeAlloy/ForgeAlloyUnity/Assets/ForgeNetworking/Networking/Messaging/ForgeMessage.cs +++ b/ForgeAlloy/ForgeAlloyUnity/Assets/ForgeNetworking/Networking/Messaging/ForgeMessage.cs @@ -1,4 +1,4 @@ -using Forge.Serialization; +using Forge.Serialization; namespace Forge.Networking.Messaging { @@ -9,9 +9,11 @@ public abstract class ForgeMessage : IMessage public abstract IMessageInterpreter Interpreter { get; } public abstract void Serialize(BMSByte buffer); public abstract void Deserialize(BMSByte buffer); + public bool BlockSent { get; set; } = false; public void Sent() { - OnMessageSent?.Invoke(this); + if (!BlockSent) + OnMessageSent?.Invoke(this); } } } From 5a16a03846482e73df2fbe567e69b08ea84bc7c2 Mon Sep 17 00:00:00 2001 From: zaddo67 Date: Fri, 8 Jan 2021 22:32:03 +1000 Subject: [PATCH 5/6] Allow Message to be sent multiple times --- .../ForgeNetworking/Networking/Messaging/ForgeMessage.cs | 5 ++--- .../ForgeNetworking/Networking/Messaging/IMessage.cs | 3 ++- .../Networking/Messaging/MessagePoolMulti.cs | 8 ++++++++ 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/ForgeAlloy/ForgeAlloyUnity/Assets/ForgeNetworking/Networking/Messaging/ForgeMessage.cs b/ForgeAlloy/ForgeAlloyUnity/Assets/ForgeNetworking/Networking/Messaging/ForgeMessage.cs index eb177e27..93bc131d 100644 --- a/ForgeAlloy/ForgeAlloyUnity/Assets/ForgeNetworking/Networking/Messaging/ForgeMessage.cs +++ b/ForgeAlloy/ForgeAlloyUnity/Assets/ForgeNetworking/Networking/Messaging/ForgeMessage.cs @@ -9,11 +9,10 @@ public abstract class ForgeMessage : IMessage public abstract IMessageInterpreter Interpreter { get; } public abstract void Serialize(BMSByte buffer); public abstract void Deserialize(BMSByte buffer); - public bool BlockSent { get; set; } = false; + public bool IsPooled { get; set; } = false; public void Sent() { - if (!BlockSent) - OnMessageSent?.Invoke(this); + OnMessageSent?.Invoke(this); } } } diff --git a/ForgeAlloy/ForgeAlloyUnity/Assets/ForgeNetworking/Networking/Messaging/IMessage.cs b/ForgeAlloy/ForgeAlloyUnity/Assets/ForgeNetworking/Networking/Messaging/IMessage.cs index c2111ffa..35d93a9f 100644 --- a/ForgeAlloy/ForgeAlloyUnity/Assets/ForgeNetworking/Networking/Messaging/IMessage.cs +++ b/ForgeAlloy/ForgeAlloyUnity/Assets/ForgeNetworking/Networking/Messaging/IMessage.cs @@ -1,4 +1,4 @@ -using Forge.Serialization; +using Forge.Serialization; namespace Forge.Networking.Messaging { @@ -12,5 +12,6 @@ public interface IMessage void Serialize(BMSByte buffer); void Deserialize(BMSByte buffer); void Sent(); + bool IsPooled { get; set; } } } diff --git a/ForgeAlloy/ForgeAlloyUnity/Assets/ForgeNetworking/Networking/Messaging/MessagePoolMulti.cs b/ForgeAlloy/ForgeAlloyUnity/Assets/ForgeNetworking/Networking/Messaging/MessagePoolMulti.cs index 3b785089..63ec38a7 100644 --- a/ForgeAlloy/ForgeAlloyUnity/Assets/ForgeNetworking/Networking/Messaging/MessagePoolMulti.cs +++ b/ForgeAlloy/ForgeAlloyUnity/Assets/ForgeNetworking/Networking/Messaging/MessagePoolMulti.cs @@ -18,7 +18,10 @@ public IMessage Get(Type t) // Try to dequeue, but if locked default to create new IMessage item; if (pool.TryDequeue(out item)) + { + item.IsPooled = false; return item; + } else return CreateNewMessageForPool(t, pool); } } @@ -33,7 +36,10 @@ public IMessage Get(Type t) // Try to dequeue, but if locked default to create new IMessage item; if (pool.TryDequeue(out item)) + { + item.IsPooled = false; return (T)item; + } else return CreateNewMessageForPool(pool); } } @@ -64,6 +70,8 @@ private IMessage CreateNewMessageForPool(Type t, ConcurrentQueue pool) private void Release(IMessage message) { + if (message.IsPooled) return; // Message has already been returned to pool + message.IsPooled = true; ConcurrentQueue pool = GetPool(message.GetType()); pool.Enqueue(message); } From 21be4fa0d5aae0e3518e152160a7d4c4880f7256 Mon Sep 17 00:00:00 2001 From: zaddo67 Date: Sun, 23 May 2021 13:20:07 +1000 Subject: [PATCH 6/6] SendReliable Message, releasing message before acknowledged --- .../Networking/ForgeNetworkMediator.cs | 4 ++-- .../Networking/Messaging/ForgeMessage.cs | 8 +++++++ .../Networking/Messaging/ForgeMessageBus.cs | 2 +- .../Messaging/ForgeMessageRepository.cs | 22 +++++++++++++++++++ .../Networking/Messaging/IMessage.cs | 3 +++ .../Networking/Messaging/MessagePoolMulti.cs | 3 +++ 6 files changed, 39 insertions(+), 3 deletions(-) diff --git a/ForgeAlloy/ForgeAlloyUnity/Assets/ForgeNetworking/Networking/ForgeNetworkMediator.cs b/ForgeAlloy/ForgeAlloyUnity/Assets/ForgeNetworking/Networking/ForgeNetworkMediator.cs index 93f46038..dd48cf60 100644 --- a/ForgeAlloy/ForgeAlloyUnity/Assets/ForgeNetworking/Networking/ForgeNetworkMediator.cs +++ b/ForgeAlloy/ForgeAlloyUnity/Assets/ForgeNetworking/Networking/ForgeNetworkMediator.cs @@ -91,12 +91,12 @@ public void SendReliableMessage(IMessage message) public void SendReliableMessage(IMessage message, INetPlayer player) { - MessageBus.SendMessage(message, SocketFacade.ManagedSocket, player.EndPoint); + MessageBus.SendReliableMessage(message, SocketFacade.ManagedSocket, player.EndPoint); } public void SendReliableMessage(IMessage message, EndPoint endpoint) { - MessageBus.SendMessage(message, SocketFacade.ManagedSocket, endpoint); + MessageBus.SendReliableMessage(message, SocketFacade.ManagedSocket, endpoint); } } } diff --git a/ForgeAlloy/ForgeAlloyUnity/Assets/ForgeNetworking/Networking/Messaging/ForgeMessage.cs b/ForgeAlloy/ForgeAlloyUnity/Assets/ForgeNetworking/Networking/Messaging/ForgeMessage.cs index 93bc131d..e4931955 100644 --- a/ForgeAlloy/ForgeAlloyUnity/Assets/ForgeNetworking/Networking/Messaging/ForgeMessage.cs +++ b/ForgeAlloy/ForgeAlloyUnity/Assets/ForgeNetworking/Networking/Messaging/ForgeMessage.cs @@ -10,8 +10,16 @@ public abstract class ForgeMessage : IMessage public abstract void Serialize(BMSByte buffer); public abstract void Deserialize(BMSByte buffer); public bool IsPooled { get; set; } = false; + public bool IsBuffered { get; set; } = false; + public bool IsSent { get; set; } = false; public void Sent() { + IsSent = true; + OnMessageSent?.Invoke(this); + } + public void Unbuffered() + { + IsBuffered = false; OnMessageSent?.Invoke(this); } } diff --git a/ForgeAlloy/ForgeAlloyUnity/Assets/ForgeNetworking/Networking/Messaging/ForgeMessageBus.cs b/ForgeAlloy/ForgeAlloyUnity/Assets/ForgeNetworking/Networking/Messaging/ForgeMessageBus.cs index 9b25faed..73d25283 100644 --- a/ForgeAlloy/ForgeAlloyUnity/Assets/ForgeNetworking/Networking/Messaging/ForgeMessageBus.cs +++ b/ForgeAlloy/ForgeAlloyUnity/Assets/ForgeNetworking/Networking/Messaging/ForgeMessageBus.cs @@ -70,8 +70,8 @@ public void SendMessage(IMessage message, ISocket sender, EndPoint receiver) public IMessageReceiptSignature SendReliableMessage(IMessage message, ISocket sender, EndPoint receiver) { message.Receipt = AbstractFactory.Get().GetNew(); - SendMessage(message, sender, receiver); _messageRepeater.AddMessageToRepeat(message, receiver); + SendMessage(message, sender, receiver); return message.Receipt; } diff --git a/ForgeAlloy/ForgeAlloyUnity/Assets/ForgeNetworking/Networking/Messaging/ForgeMessageRepository.cs b/ForgeAlloy/ForgeAlloyUnity/Assets/ForgeNetworking/Networking/Messaging/ForgeMessageRepository.cs index eebbb2a6..be45a6ab 100644 --- a/ForgeAlloy/ForgeAlloyUnity/Assets/ForgeNetworking/Networking/Messaging/ForgeMessageRepository.cs +++ b/ForgeAlloy/ForgeAlloyUnity/Assets/ForgeNetworking/Networking/Messaging/ForgeMessageRepository.cs @@ -30,6 +30,7 @@ public void Clear() lock (_messages) { _messages.Clear(); + // TODO: Need to unbuffer the messages, otherwise they will never return to message pool } } @@ -74,6 +75,7 @@ public void AddMessage(IMessage message, EndPoint sender) kv = new Dictionary(); _messages.Add(sender, kv); } + message.IsBuffered = true; kv.Add(message.Receipt, message); } } @@ -104,11 +106,24 @@ public void AddMessage(IMessage message, EndPoint sender, int ttlMilliseconds) public void RemoveAllFor(EndPoint sender) { + var copy = new List(); + lock (_messages) { var removals = new List(); + if (_messages.TryGetValue(sender, out var kv)) + { + foreach (var mkv in kv) + copy.Add(mkv.Value); + } _messages.Remove(sender); } + + try + { + foreach (var m in copy) m.Unbuffered(); + } + catch { } } public void RemoveMessage(EndPoint sender, IMessage message) @@ -127,7 +142,14 @@ private void RemoveFromMessageLookup(EndPoint sender, IMessageReceiptSignature r lock (_messages) { if (_messages.TryGetValue(sender, out var kv)) + { + try + { + kv[receipt].Unbuffered(); + } + catch { } // Catch just in case message already removed kv.Remove(receipt); + } } } diff --git a/ForgeAlloy/ForgeAlloyUnity/Assets/ForgeNetworking/Networking/Messaging/IMessage.cs b/ForgeAlloy/ForgeAlloyUnity/Assets/ForgeNetworking/Networking/Messaging/IMessage.cs index 35d93a9f..3660822d 100644 --- a/ForgeAlloy/ForgeAlloyUnity/Assets/ForgeNetworking/Networking/Messaging/IMessage.cs +++ b/ForgeAlloy/ForgeAlloyUnity/Assets/ForgeNetworking/Networking/Messaging/IMessage.cs @@ -12,6 +12,9 @@ public interface IMessage void Serialize(BMSByte buffer); void Deserialize(BMSByte buffer); void Sent(); + void Unbuffered(); bool IsPooled { get; set; } + bool IsBuffered { get; set; } + bool IsSent { get; set; } } } diff --git a/ForgeAlloy/ForgeAlloyUnity/Assets/ForgeNetworking/Networking/Messaging/MessagePoolMulti.cs b/ForgeAlloy/ForgeAlloyUnity/Assets/ForgeNetworking/Networking/Messaging/MessagePoolMulti.cs index 63ec38a7..1a76e2e1 100644 --- a/ForgeAlloy/ForgeAlloyUnity/Assets/ForgeNetworking/Networking/Messaging/MessagePoolMulti.cs +++ b/ForgeAlloy/ForgeAlloyUnity/Assets/ForgeNetworking/Networking/Messaging/MessagePoolMulti.cs @@ -71,6 +71,9 @@ private IMessage CreateNewMessageForPool(Type t, ConcurrentQueue pool) private void Release(IMessage message) { if (message.IsPooled) return; // Message has already been returned to pool + if (!message.IsSent) return; // Message has not been sent, not ready to return to pool + if (message.IsBuffered) return; // Message is still buffered, not ready to return to pool + message.IsSent = false; message.IsPooled = true; ConcurrentQueue pool = GetPool(message.GetType()); pool.Enqueue(message);