ObjectDeliverer

A library that makes it easy to switch between various communication methods such as TCP/IP, UDP, shared memory, and file-based communication.

Overview

ObjectDeliverer is a flexible library designed to simplify data communication in Unreal Engine projects. It allows you to easily switch between various communication protocols such as TCP/IP, UDP, shared memory, and file transfer, and is available for both C++ and Blueprint.

The biggest feature of this plugin is that you barely need to change your code when switching communication methods. By simply changing the protocol, you can keep the rest of your code as it is.

This makes it easy, for example, to switch communication implemented with TCP/IP to UDP. This is especially useful for projects in the prototyping phase, where you may want to try out different communication methods.

Key Features

  • Support for various communication protocols (TCP/IP, UDP, shared memory, file, etc.)
  • Easy switching between protocols
  • Full-feature support for both C++ and Blueprint
  • Asynchronous communication (communication without blocking the main thread)
  • Flexible data format support (binary, plain text, and JSON text)

Usage Examples

The following is a basic implementation example of creating a TCP server using ObjectDeliverer.

Blueprint
C++
void UMyClass::Start()
{
    auto deliverer = UObjectDelivererManager::CreateObjectDelivererManager();

    // Set up event handlers
    deliverer->Connected.AddDynamic(this, &UMyClass::OnConnect);
    deliverer->Disconnected.AddDynamic(this, &UMyClass::OnDisConnect);
    deliverer->ReceiveData.AddDynamic(this, &UMyClass::OnReceive);

    // Start communication
    // Protocol: TCP/IP Server
    // Data division rule: Header(Size) + Body
    // Serialization method: Byte array
    deliverer->Start(UProtocolFactory::CreateProtocolTcpIpServer(9099),
                     UPacketRuleFactory::CreatePacketRuleSizeBody());
}

void UMyClass::OnConnect(UObjectDelivererProtocol* ClientSocket)
{
    // Send data
    TArray<uint8> buffer;
    deliverer->Send(buffer);
}

void UMyClass::OnDisConnect(UObjectDelivererProtocol* ClientSocket)
{
    // Handle disconnection
    UE_LOG(LogTemp, Log, TEXT("closed"));
}

void UMyClass::OnReceive(UObjectDelivererProtocol* ClientSocket, const TArray<uint8>& Buffer)
{
    // Handle received data
}


Switching Protocols

To change the protocol, simply pass a different protocol to the Start method. By making the following change to the above example, you can switch to the UDP transmission protocol.

Blueprint
C++
// UDP Sender
deliverer->Start(UProtocolFactory::CreateProtocolUdpSocketSender("192.168.0.100", 9099),
                 UPacketRuleFactory::CreatePacketRuleSizeBody());

ObjectDeliverer supports the following protocols. You can also create your own custom protocols.

  • TCP/IP Server
  • TCP/IP Client
  • UDP Sender
  • UDP Receiver
  • Shared Memory(Windows only)
  • File writer
  • File reader
  • Reflection
TCP/IP Server, Client

This is a protocol for TCP/IP communication. Since TCP/IP supports one-to-many communication, multiple clients can connect to a single server.

Additionally, it features packet retransmission, so messages sent are reliably delivered to the recipient.

UDP Sender, Receiver

This is a protocol for UDP communication. Unlike TCP/IP, UDP communication sends messages unilaterally to the recipient without a connection step.

Since it does not have packet retransmission functionality, there may be cases where packets are not delivered depending on network conditions. However, this also means it offers better performance compared to TCP/IP.

Shared Memory

Shared Memory creates a memory space that can be shared by multiple applications, allowing messages to be written to and read from this space.

Since it is not network communication, sending and receiving values is only possible on the same PC.

Additionally, there is no way for the receiver to know when data has been sent (written), so the receiving side must periodically read the memory to check for new writes. ObjectDeliverer handles this process automatically, so users typically do not need to be concerned about it. However, if you are reading memory created by a third party, you should check what rules are used for reading.

While Shared Memory can only be used on the same PC (which is a disadvantage), it offers superior read/write speed compared to other methods, making it suitable for exchanging large messages.

Currently, this protocol is only available on Windows.

File writer, reader

File is a protocol for writing and reading messages to and from a specific file.

Its behavior is similar to Shared Memory, but since it writes to an actual file, messages can be checked even after the application has closed.

Therefore, it is suitable for use cases where you need to store some kind of data.

Reflection

This is a protocol that performs message sending and receiving on itself. When a message is sent, a receive event occurs on the same instance. Therefore, it cannot be used to exchange messages with other instances.

It is mainly intended for debugging purposes during development.

Switching Packet Fragmentation Rules

Protocols such as TCP/IP may split a single message into multiple packets or, conversely, combine multiple messages into a single packet.

To address this, ObjectDeliverer allows you to configure packet fragmentation rules to solve this problem.

Just like switching protocols, you can specify the packet fragmentation rule by passing it to the Start method.

Blueprint
C++
// UDP Sender
deliverer->Start(UProtocolFactory::CreateProtocolUdpSocketSender("192.168.0.100", 9099),
                 UPacketRuleFactory::CreatePacketRuleSizeBody());

ObjectDeliverer supports the following fragmentation rules. You can also create your own custom rules.

  • FixedLength
  • Terminate
  • SizeBody
  • Nodivision

Both the sender and receiver must use the same fragmentation rule. Therefore, if you need to communicate with a program created by a third party, you should check in advance which fragmentation rule it uses.

FixedLenth

FixedLength is a method of splitting messages by setting a fixed length for each message. Since the packet size is fixed for every transmission, the splitting logic becomes simple. However, there is a limitation: messages larger than the specified size cannot be sent.

Terminate

Terminate is a method of delimiting messages by specifying a particular value as the separator. A commonly used example of this is using a newline character to separate messages. With this method, the length of messages sent can be changed dynamically, but since the end value must be searched for each time, performance is slightly reduced.

SizeBody

SizeBody is a method where the message size is embedded at the beginning of the message. This approach allows the message size to be dynamic, and since the logic for splitting packets is relatively simple, it also offers good performance.

Nodivision

Nodivision treats each received packet as a single message without splitting or combining packets.

Switching DeliveryBox

By default, ObjectDeliverer sends and receives byte arrays, but it can convert these to data in a specified format.

By using this feature, you no longer need to manually convert data to a byte array each time.

Blueprint
C++
auto deliverybox = UDeliveryBoxFactory::CreateObjectDeliveryBoxUsingJson(SampleObject::StaticClass());
deliverybox->Received.AddDynamic(this, &UMyClass::OnReceiveObject);

deliverer->Start(UProtocolFactory::CreateProtocolTcpIpServer(9099),
                 UPacketRuleFactory::CreatePacketRuleSizeBody(),
                 deliverybox);

When using DeliveryBox, please note that message sending and receiving are performed via DeliveryBox, not through ObjectDelivererManager.

Blueprint
C++
auto message = NewObject<SampleMessage>();
deliveryBox->Send(message);

ObjectDeliverer supports the following DeliveryBoxes. You can also create your own custom DeliveryBox.

  • ObjectDeliveryBoxUsingJson
  • Utf8StringDeliveryBox

ObjectDeliveryBoxUsingJson

ObjectDeliveryBoxUsingJson is a DeliveryBox that converts any user-defined UObject class to and from a JSON string for sending and receiving.

Since all classes that can be used in Unreal Engine inherit from UObject, many class instances can be sent and received as they are.

Exchanging communication messages in JSON format is a common approach in other programming languages as well, so by using this, it is also possible to send and receive messages with other applications.

Utf8StringDeliveryBox

Utf8StringDeliveryBox is a DeliveryBox for sending and receiving arbitrary strings as they are. Encoding is performed using UTF-8.

FAQ

You can check frequently asked questions here.