diff --git a/Source/Engine/Networking/Drivers/ENetDriver.h b/Source/Engine/Networking/Drivers/ENetDriver.h
index 86e4635e0..b3096e716 100644
--- a/Source/Engine/Networking/Drivers/ENetDriver.h
+++ b/Source/Engine/Networking/Drivers/ENetDriver.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2012-2021 Wojciech Figat. All rights reserved.
+// Copyright (c) 2012-2021 Wojciech Figat. All rights reserved.
#pragma once
@@ -10,6 +10,9 @@
#include "Engine/Core/Collections/Dictionary.h"
#include "Engine/Scripting/ScriptingType.h"
+///
+/// Low-level network transport interface implementation based on ENet library.
+///
API_CLASS(Namespace="FlaxEngine.Networking", Sealed) class FLAXENGINE_API ENetDriver : public INetworkDriver
{
DECLARE_SCRIPTING_TYPE_MINIMAL(ENetDriver);
diff --git a/Source/Engine/Networking/INetworkDriver.h b/Source/Engine/Networking/INetworkDriver.h
index bcdf65079..810f4e046 100644
--- a/Source/Engine/Networking/INetworkDriver.h
+++ b/Source/Engine/Networking/INetworkDriver.h
@@ -1,26 +1,98 @@
-// Copyright (c) 2012-2021 Wojciech Figat. All rights reserved.
+// Copyright (c) 2012-2021 Wojciech Figat. All rights reserved.
#pragma once
#include "Engine/Scripting/ScriptingType.h"
#include "Types.h"
+///
+/// Basic interface for the low-level network transport/driver.
+///
API_INTERFACE(Namespace="FlaxEngine.Networking") class FLAXENGINE_API INetworkDriver
{
DECLARE_SCRIPTING_TYPE_MINIMAL(INetworkDriver);
public:
+ ///
+ /// Initializes the instance of this network driver using given configuration.
+ ///
+ /// The peer that this driver has been assigned to.
+ /// The network config to use to configure this driver.
virtual void Initialize(NetworkPeer* host, const NetworkConfig& config) = 0;
+
+ ///
+ /// Disposes this driver making it no longer usable.
+ /// Reserved for resource deallocation etc.
+ ///
virtual void Dispose() = 0;
+ ///
+ /// Starts listening for incoming connections.
+ /// Once this is called, this driver becomes a server.
+ ///
+ /// True when succeeded.
virtual bool Listen() = 0;
+
+ ///
+ /// Starts connection handshake with the end point specified in the structure.
+ /// Once this is called, this driver becomes a client.
+ ///
+ /// True when succeeded.
virtual bool Connect() = 0;
+
+ ///
+ /// Disconnects from the server.
+ ///
+ /// Can be used only by the client!
virtual void Disconnect() = 0;
+
+ ///
+ /// Disconnects given connection from the server.
+ ///
+ /// Can be used only by the server!
virtual void Disconnect(const NetworkConnection& connection) = 0;
+ ///
+ /// Tries to pop an network event from the queue.
+ ///
+ /// The pointer to event structure.
+ /// True when succeeded and the event can be processed.
virtual bool PopEvent(NetworkEvent* eventPtr) = 0;
+ ///
+ /// Sends given message over specified channel to the server.
+ ///
+ /// The channel to send the message over.
+ /// The message.
+ /// Can be used only by the client!
+ ///
+ /// Do not recycle the message after calling this.
+ /// This function automatically recycles the message.
virtual void SendMessage(NetworkChannelType channelType, const NetworkMessage& message) = 0;
+
+ ///
+ /// Sends given message over specified channel to the given client connection (target).
+ ///
+ /// The channel to send the message over.
+ /// The message.
+ /// The client connection to send the message to.
+ /// Can be used only by the server!
+ ///
+ /// Do not recycle the message after calling this.
+ /// This function automatically recycles the message.
+ ///
virtual void SendMessage(NetworkChannelType channelType, const NetworkMessage& message, NetworkConnection target) = 0;
+
+ ///
+ /// Sends given message over specified channel to the given client connection (target).
+ ///
+ /// The channel to send the message over.
+ /// The message.
+ /// The connections list to send the message to.
+ /// Can be used only by the server!
+ ///
+ /// Do not recycle the message after calling this.
+ /// This function automatically recycles the message.
+ ///
virtual void SendMessage(NetworkChannelType channelType, const NetworkMessage& message, Array targets) = 0;
// TODO: Stats API
diff --git a/Source/Engine/Networking/NetworkChannelType.h b/Source/Engine/Networking/NetworkChannelType.h
index e2af9c34e..e5fbc8d9b 100644
--- a/Source/Engine/Networking/NetworkChannelType.h
+++ b/Source/Engine/Networking/NetworkChannelType.h
@@ -1,16 +1,40 @@
-// Copyright (c) 2012-2021 Wojciech Figat. All rights reserved.
+// Copyright (c) 2012-2021 Wojciech Figat. All rights reserved.
#pragma once
#include "Engine/Scripting/ScriptingType.h"
+///
+/// The low-level network channel type for message sending.
+///
API_ENUM(Namespace="FlaxEngine.Networking") enum class NetworkChannelType
{
+ ///
+ /// Invalid channel type.
+ ///
None = 0,
-
+
+ ///
+ /// Unreliable channel type.
+ /// Messages can be lost or arrive out-of-order.
+ ///
Unreliable,
+
+ ///
+ /// Unreliable-ordered channel type.
+ /// Messages can be lost but always arrive in order.
+ ///
UnreliableOrdered,
-
+
+ ///
+ /// Reliable channel type.
+ /// Messages won't be lost but may arrive out-of-order.
+ ///
Reliable,
+
+ ///
+ /// Reliable-ordered channel type.
+ /// Messages won't be lost and always arrive in order.
+ ///
ReliableOrdered
};
diff --git a/Source/Engine/Networking/NetworkConfig.h b/Source/Engine/Networking/NetworkConfig.h
index 2330847a3..2a6db2fc1 100644
--- a/Source/Engine/Networking/NetworkConfig.h
+++ b/Source/Engine/Networking/NetworkConfig.h
@@ -1,32 +1,51 @@
-// Copyright (c) 2012-2021 Wojciech Figat. All rights reserved.
+// Copyright (c) 2012-2021 Wojciech Figat. All rights reserved.
#pragma once
#include "Engine/Platform/Network.h"
-API_ENUM(Namespace="FlaxEngine.Networking") enum class NetworkTransportType
+///
+/// Network driver implementations enum.
+///
+API_ENUM(Namespace="FlaxEngine.Networking") enum class NetworkDriverType
{
+ ///
+ /// Invalid network driver implementation.
+ ///
Undefined = 0,
-
+
+ ///
+ /// ENet library based network driver implementation.
+ ///
ENet
};
+///
+/// Low-level network configuration structure. Provides settings for the network driver and all internal components.
+///
API_STRUCT(Namespace="FlaxEngine.Networking") struct FLAXENGINE_API NetworkConfig
{
DECLARE_SCRIPTING_TYPE_MINIMAL(NetworkConfig);
public:
+ ///
+ /// The network driver that will be used to create the peer.
+ /// To allow two peers to connect, they must use the same host.
+ ///
API_FIELD()
NetworkTransportType NetworkDriverType = NetworkTransportType::ENet;
// TODO: Expose INetworkDriver as a ref not enum, when C++/C# interfaces are done.
public:
+ ///
+ /// The upper limit on how many peers can join when we're listening.
+ ///
API_FIELD()
uint16 ConnectionsLimit = 32;
///
/// Address used to connect to or listen at.
- /// Set it to "any" when you want to listen at all available addresses.
///
+ /// Set it to "any" when you want to listen at all available addresses.
/// Only IPv4 is supported.
API_FIELD()
String Address = String("127.0.0.1");
@@ -37,9 +56,20 @@ public:
API_FIELD()
uint16 Port = 7777;
+ ///
+ /// The size of a message buffer in bytes.
+ /// Should be lower than the MTU (maximal transmission unit) - typically 1500 bytes.
+ ///
API_FIELD()
- uint16 MessageSize = 1500; // MTU
+ uint16 MessageSize = 1500;
+ ///
+ /// The amount of pooled messages that can be used at once (receiving and sending!).
+ ///
+ ///
+ /// Creating more messages than this limit will result in a crash!
+ /// This should be tweaked manually to fit the needs (adjusting this value will increase/decrease memory usage)!
+ ///
API_FIELD()
- uint16 MessagePoolSize = 2048; // (RX and TX)
+ uint16 MessagePoolSize = 2048;
};
diff --git a/Source/Engine/Networking/NetworkConnection.h b/Source/Engine/Networking/NetworkConnection.h
index fe6489dd0..a93cb4ac3 100644
--- a/Source/Engine/Networking/NetworkConnection.h
+++ b/Source/Engine/Networking/NetworkConnection.h
@@ -1,13 +1,20 @@
-// Copyright (c) 2012-2021 Wojciech Figat. All rights reserved.
+// Copyright (c) 2012-2021 Wojciech Figat. All rights reserved.
#pragma once
#include "Engine/Scripting/ScriptingType.h"
+///
+/// Network connection structure - used to identify connected peers when we're listening.
+///
API_STRUCT(Namespace="FlaxEngine.Networking") struct FLAXENGINE_API NetworkConnection
{
DECLARE_SCRIPTING_TYPE_MINIMAL(NetworkConnection);
public:
- API_FIELD();
+ ///
+ /// The identifier of the connection.
+ ///
+ /// Used by network driver implementations.
+ API_FIELD()
uint32 ConnectionId;
};
diff --git a/Source/Engine/Networking/NetworkEvent.h b/Source/Engine/Networking/NetworkEvent.h
index 83caee479..d61bd9ae9 100644
--- a/Source/Engine/Networking/NetworkEvent.h
+++ b/Source/Engine/Networking/NetworkEvent.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2012-2021 Wojciech Figat. All rights reserved.
+// Copyright (c) 2012-2021 Wojciech Figat. All rights reserved.
#pragma once
@@ -6,26 +6,60 @@
#include "NetworkMessage.h"
#include "Engine/Scripting/ScriptingType.h"
+///
+/// Network event type enum contains all possible events that can be returned by PopEvent function.
+///
API_ENUM(Namespace="FlaxEngine.Networking") enum class NetworkEventType
{
+ ///
+ /// Invalid network event type.
+ ///
Undefined = 0,
+ ///
+ /// Event "connected" - client connected to our server or we've connected to the server.
+ ///
Connected,
+
+ ///
+ /// Event "disconnected" - client disconnected from our server or we've been kicked from the server.
+ ///
Disconnected,
+
+ ///
+ /// Event "disconnected" - client got a timeout from our server or we've list the connection to the server.
+ ///
Timeout,
+
+ ///
+ /// Event "message" - message received from some client or the server.
+ ///
Message
};
+///
+/// Network event structure that wraps all data needed to identify and process it.
+///
API_STRUCT(Namespace="FlaxEngine.Networking") struct FLAXENGINE_API NetworkEvent
{
DECLARE_SCRIPTING_TYPE_MINIMAL(NetworkEvent);
public:
+ ///
+ /// The type of the received event.
+ ///
API_FIELD();
NetworkEventType EventType;
-
+
+ ///
+ /// The message when this event is an "message" event - not valid in any other cases.
+ ///
API_FIELD();
NetworkMessage Message;
+ ///
+ /// The connected of the client that has sent message, connected, disconnected or got a timeout.
+ ///
+ /// Only valid when event has been received on server-peer.
API_FIELD();
NetworkConnection Sender;
};
diff --git a/Source/Engine/Networking/NetworkManager.h b/Source/Engine/Networking/NetworkManager.h
index 68ac7494e..114dc4182 100644
--- a/Source/Engine/Networking/NetworkManager.h
+++ b/Source/Engine/Networking/NetworkManager.h
@@ -1,17 +1,30 @@
-// Copyright (c) 2012-2021 Wojciech Figat. All rights reserved.
+// Copyright (c) 2012-2021 Wojciech Figat. All rights reserved.
#pragma once
#include "Engine/Scripting/ScriptingType.h"
#include "Types.h"
+///
+/// Low-level network service. Provides network peer management functionality.
+///
API_CLASS(Namespace="FlaxEngine.Networking", Static) class FLAXENGINE_API NetworkManager
{
DECLARE_SCRIPTING_TYPE_NO_SPAWN(NetworkManager);
public:
-
+ ///
+ /// Creates new peer using given configuration.
+ ///
+ /// The configuration to create and setup new peer.
+ /// The peer.
+ /// Peer should be destroyed using once it is no longer in use.
API_FUNCTION()
static NetworkPeer* CreatePeer(const NetworkConfig& config);
+
+ ///
+ /// Shutdowns and destroys given peer.
+ ///
+ /// The peer to destroy.
API_FUNCTION()
static void ShutdownPeer(NetworkPeer* peer);
diff --git a/Source/Engine/Networking/NetworkMessage.cpp b/Source/Engine/Networking/NetworkMessage.cpp
index bf92b0237..0ec7b5702 100644
--- a/Source/Engine/Networking/NetworkMessage.cpp
+++ b/Source/Engine/Networking/NetworkMessage.cpp
@@ -1,4 +1,4 @@
-// Copyright (c) 2012-2021 Wojciech Figat. All rights reserved.
+// Copyright (c) 2012-2021 Wojciech Figat. All rights reserved.
#include "NetworkMessage.h"
@@ -15,3 +15,8 @@ void NetworkMessage::ReadBytes(uint8* bytes, const int numBytes)
Platform::MemoryCopy(bytes, Buffer + Position, numBytes);
Position += numBytes;
}
+
+bool NetworkMessage::IsValid() const
+{
+ return Buffer != nullptr && BufferSize > 0;
+}
diff --git a/Source/Engine/Networking/NetworkMessage.cs b/Source/Engine/Networking/NetworkMessage.cs
index b721ae7fa..42b0fb09e 100644
--- a/Source/Engine/Networking/NetworkMessage.cs
+++ b/Source/Engine/Networking/NetworkMessage.cs
@@ -12,11 +12,11 @@ namespace FlaxEngine.Networking
/// Writes raw bytes into the message.
///
/// The bytes that will be written.
- /// The amount of bytes to write from the pointer.
+ /// The amount of bytes to write from the bytes pointer.
public void WriteBytes(byte* bytes, int length)
{
Assert.IsTrue(Position + length <= BufferSize, $"Could not write data of length {length} into message with id={MessageId}! Current write position={Position}");
- Utils.MemoryCopy(new IntPtr(bytes), new IntPtr(Buffer + Position), length);
+ Utils.MemoryCopy(new IntPtr(bytes), new IntPtr(Buffer + Position), (ulong)length);
Position += (uint)length;
Length = Position;
}
@@ -26,13 +26,13 @@ namespace FlaxEngine.Networking
///
///
/// The buffer pointer that will be used to store the bytes.
- /// Should be of the same length as or longer.
+ /// Should be of the same length as length or longer.
///
- /// The minimal amount of bytes that the contains.
+ /// The minimal amount of bytes that the buffer contains.
public void ReadBytes(byte* buffer, int length)
{
Assert.IsTrue(Position + length <= Length, $"Could not read data of length {length} from message with id={MessageId} and size of {Length}B! Current read position={Position}");
- Utils.MemoryCopy(new IntPtr(Buffer + Position), new IntPtr(buffer), length);
+ Utils.MemoryCopy(new IntPtr(Buffer + Position), new IntPtr(buffer), (ulong)length);
Position += (uint)length;
}
@@ -40,7 +40,7 @@ namespace FlaxEngine.Networking
/// Writes raw bytes into the message.
///
/// The bytes that will be written.
- /// The amount of bytes to write from the array.
+ /// The amount of bytes to write from the bytes array.
public void WriteBytes(byte[] bytes, int length)
{
fixed (byte* bytesPtr = bytes)
@@ -54,9 +54,9 @@ namespace FlaxEngine.Networking
///
///
/// The buffer that will be used to store the bytes.
- /// Should be of the same length as or longer.
+ /// Should be of the same length as length or longer.
///
- /// The minimal amount of bytes that the contains.
+ /// The minimal amount of bytes that the buffer contains.
public void ReadBytes(byte[] buffer, int length)
{
fixed (byte* bufferPtr = buffer)
diff --git a/Source/Engine/Networking/NetworkMessage.h b/Source/Engine/Networking/NetworkMessage.h
index 5562b617f..3acdbfa17 100644
--- a/Source/Engine/Networking/NetworkMessage.h
+++ b/Source/Engine/Networking/NetworkMessage.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2012-2021 Wojciech Figat. All rights reserved.
+// Copyright (c) 2012-2021 Wojciech Figat. All rights reserved.
#pragma once
@@ -9,28 +9,52 @@
#include "Engine/Core/Types/String.h"
#include "Engine/Scripting/ScriptingType.h"
+///
+/// Network message structure. Provides raw data writing and reading to the message buffer.
+///
API_STRUCT(Namespace="FlaxEngine.Networking") struct FLAXENGINE_API NetworkMessage
{
DECLARE_SCRIPTING_TYPE_MINIMAL(NetworkMessage);
public:
+ ///
+ /// The raw message buffer.
+ ///
API_FIELD()
uint8* Buffer = nullptr;
-
+
+ ///
+ /// The unique, internal message identifier.
+ ///
API_FIELD()
uint32 MessageId = 0;
-
+
+ ///
+ /// The size in bytes of the buffer that this message has.
+ ///
API_FIELD()
uint32 BufferSize = 0;
-
+
+ ///
+ /// The length in bytes of this message.
+ ///
API_FIELD()
uint32 Length = 0;
-
+
+ ///
+ /// The position in bytes in buffer where the next read/write will occur.
+ ///
API_FIELD()
uint32 Position = 0;
public:
+ ///
+ /// Initializes default values of the structure.
+ ///
NetworkMessage() = default;
-
+
+ ///
+ /// Initializes values of the structure.
+ ///
NetworkMessage(uint8* buffer, uint32 messageId, uint32 bufferSize, uint32 length, uint32 position) :
Buffer(buffer), MessageId(messageId), BufferSize(bufferSize), Length(length), Position(position)
{ }
@@ -38,7 +62,21 @@ public:
~NetworkMessage() = default;
public:
+ ///
+ /// Writes raw bytes into the message.
+ ///
+ /// The bytes that will be written.
+ /// The amount of bytes to write from the bytes pointer.
FORCE_INLINE void WriteBytes(uint8* bytes, int numBytes);
+
+ ///
+ /// Reads raw bytes from the message into the given byte array.
+ ///
+ ///
+ /// The buffer pointer that will be used to store the bytes.
+ /// Should be of the same length as length or longer.
+ ///
+ /// The minimal amount of bytes that the buffer contains.
FORCE_INLINE void ReadBytes(uint8* bytes, int numBytes);
#define DECL_READWRITE(type, name) \
@@ -59,17 +97,26 @@ public:
DECL_READWRITE(bool, Boolean)
public:
+ ///
+ /// Writes data of type into the message.
+ ///
FORCE_INLINE void WriteVector2(const Vector2& value)
{
WriteSingle(value.X);
WriteSingle(value.Y);
}
+ ///
+ /// Reads and returns data of type from the message.
+ ///
FORCE_INLINE Vector2 ReadVector2()
{
return Vector2(ReadSingle(), ReadSingle());
}
+ ///
+ /// Writes data of type into the message.
+ ///
FORCE_INLINE void WriteVector3(const Vector3& value)
{
WriteSingle(value.X);
@@ -77,11 +124,17 @@ public:
WriteSingle(value.Z);
}
+ ///
+ /// Reads and returns data of type from the message.
+ ///
FORCE_INLINE Vector3 ReadVector3()
{
return Vector3(ReadSingle(), ReadSingle(), ReadSingle());
}
-
+
+ ///
+ /// Writes data of type into the message.
+ ///
FORCE_INLINE void WriteVector4(const Vector4& value)
{
WriteSingle(value.X);
@@ -90,11 +143,17 @@ public:
WriteSingle(value.W);
}
+ ///
+ /// Reads and returns data of type from the message.
+ ///
FORCE_INLINE Vector4 ReadVector4()
{
return Vector4(ReadSingle(), ReadSingle(), ReadSingle(), ReadSingle());
}
+ ///
+ /// Writes data of type into the message.
+ ///
FORCE_INLINE void WriteQuaternion(const Quaternion& value)
{
WriteSingle(value.X);
@@ -103,6 +162,9 @@ public:
WriteSingle(value.W);
}
+ ///
+ /// Reads and returns data of type from the message.
+ ///
FORCE_INLINE Quaternion ReadQuaternion()
{
return Quaternion(ReadSingle(), ReadSingle(), ReadSingle(), ReadSingle());
@@ -125,8 +187,8 @@ public:
}
public:
- bool IsValid() const
- {
- return Buffer != nullptr && BufferSize > 0;
- }
+ ///
+ /// Returns true if the message is valid for reading or writing.
+ ///
+ bool IsValid() const;
};
diff --git a/Source/Engine/Networking/NetworkPeer.cpp b/Source/Engine/Networking/NetworkPeer.cpp
index e8a5935ef..461fd64c6 100644
--- a/Source/Engine/Networking/NetworkPeer.cpp
+++ b/Source/Engine/Networking/NetworkPeer.cpp
@@ -1,9 +1,8 @@
-// Copyright (c) 2012-2021 Wojciech Figat. All rights reserved.
+// Copyright (c) 2012-2021 Wojciech Figat. All rights reserved.
#include "NetworkPeer.h"
#include "NetworkEvent.h"
-
#include "Drivers/ENetDriver.h"
#include "Engine/Core/Log.h"
diff --git a/Source/Engine/Networking/NetworkPeer.h b/Source/Engine/Networking/NetworkPeer.h
index fee6fc251..d66aaf5a1 100644
--- a/Source/Engine/Networking/NetworkPeer.h
+++ b/Source/Engine/Networking/NetworkPeer.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2012-2021 Wojciech Figat. All rights reserved.
+// Copyright (c) 2012-2021 Wojciech Figat. All rights reserved.
#pragma once
@@ -9,7 +9,10 @@
#include "Engine/Core/Collections/Array.h"
-API_CLASS(sealed, NoSpawn, Namespace="FlaxEngine.Networking") class FLAXENGINE_API NetworkPeer final : public PersistentScriptingObject
+///
+/// Low-level network peer class. Provides server-client communication functions, message processing and sending.
+///
+API_CLASS(sealed, NoSpawn, Namespace = "FlaxEngine.Networking") class FLAXENGINE_API NetworkPeer final : public PersistentScriptingObject
{
DECLARE_SCRIPTING_TYPE_NO_SPAWN(NetworkHost);
friend class NetworkManager;
@@ -22,6 +25,9 @@ public:
Array MessagePool;
public:
+ ///
+ /// Initializes a new instance of the class.
+ ///
NetworkPeer() : PersistentScriptingObject(SpawnParams(Guid::New(), TypeInitializer))
{
}
@@ -35,39 +41,112 @@ private:
void DisposeMessageBuffers();
public:
+ ///
+ /// Starts listening for incoming connections.
+ /// Once this is called, this peer becomes a server.
+ ///
+ /// True when succeeded.
API_FUNCTION()
bool Listen();
-
+
+ ///
+ /// Starts connection handshake with the end point specified in the structure.
+ /// Once this is called, this peer becomes a client.
+ ///
+ /// True when succeeded.
API_FUNCTION()
bool Connect();
-
+
+ ///
+ /// Disconnects from the server.
+ ///
+ /// Can be used only by the client!
API_FUNCTION()
void Disconnect();
-
+
+ ///
+ /// Disconnects given connection from the server.
+ ///
+ /// Can be used only by the server!
API_FUNCTION()
void Disconnect(const NetworkConnection& connection);
-
+
+ ///
+ /// Tries to pop an network event from the queue.
+ ///
+ /// The reference to event structure.
+ /// True when succeeded and the event can be processed.
API_FUNCTION()
bool PopEvent(API_PARAM(out) NetworkEvent& eventRef);
+ ///
+ /// Acquires new message from the pool.
+ /// Cannot acquire more messages than the limit specified in the structure.
+ ///
+ /// The acquired message.
+ /// Make sure to recycle the message to this peer once it is no longer needed!
API_FUNCTION()
NetworkMessage CreateMessage();
-
+
+ ///
+ /// Returns given message to the pool.
+ ///
+ /// Make sure that this message belongs to the peer and has not been recycled already (debug build checks for this)!
API_FUNCTION()
void RecycleMessage(const NetworkMessage& message);
+ ///
+ /// Acquires new message from the pool and setups it for sending.
+ ///
+ /// The acquired message.
API_FUNCTION()
NetworkMessage BeginSendMessage();
-
+
+ ///
+ /// Aborts given message send. This effectively deinitializes the message and returns it to the pool.
+ ///
+ /// The message.
API_FUNCTION()
void AbortSendMessage(const NetworkMessage& message);
-
+
+ ///
+ /// Sends given message over specified channel to the server.
+ ///
+ /// The channel to send the message over.
+ /// The message.
+ /// Can be used only by the client!
+ ///
+ /// Do not recycle the message after calling this.
+ /// This function automatically recycles the message.
+ ///
API_FUNCTION()
bool EndSendMessage(NetworkChannelType channelType, const NetworkMessage& message);
-
+
+ ///
+ /// Sends given message over specified channel to the given client connection (target).
+ ///
+ /// The channel to send the message over.
+ /// The message.
+ /// The client connection to send the message to.
+ /// Can be used only by the server!
+ ///
+ /// Do not recycle the message after calling this.
+ /// This function automatically recycles the message.
+ ///
API_FUNCTION()
bool EndSendMessage(NetworkChannelType channelType, const NetworkMessage& message, const NetworkConnection& target);
-
+
+ ///
+ /// Sends given message over specified channel to the given client connection (target).
+ ///
+ /// The channel to send the message over.
+ /// The message.
+ /// The connections list to send the message to.
+ /// Can be used only by the server!
+ ///
+ /// Do not recycle the message after calling this.
+ /// This function automatically recycles the message.
+ ///
API_FUNCTION()
bool EndSendMessage(NetworkChannelType channelType, const NetworkMessage& message, Array targets);