dagon:network — асинхронный UDP-клиент для игр

В Dagon грядет расширение для создания сетевых игр! Я решил интегрировать библиотеку ENet и написать поверх нее легковесный клиент, при помощи которого игра сможет взаимодействовать с UDP-сервером. Причем это работает через менеджер событий и асинхронную систему обмена сообщениями (dagon.core.messaging), о которой я писал в соответствующем посте. Это дает сразу два преимущества: сетевой клиент не блокирует игровую логику (поскольку работает в собственном потоке), и гарантируется порядок отправки сообщений (сообщения добавляются в SPSC-очередь).

Выглядит это так:

import dagon.ext.network;

class TestScene: Scene
{
    MyGame game;
    NetworkClient netClient;

    this(MyGame game)
    {
        super(game);
        this.game = game;
    }

    override void afterLoad()
    {
        // Инициализация игры...

        netClient = New!NetworkClient("GameClient",
            game.networkManager, "XXX.XXX.XXX.XXX", 1234, this);
        netClient.run();

        eventManager.messageBroker.enabled = true;
    }

    override void onMessage(
        int domain, string sender, string message, void* payload)
    {
        if (sender == "GameClient")
        {
            logInfo("[Server] ", message);
        }
    }

    override void onKeyDown(int key)
    {
        send("GameClient", "Hello, World!");
    }
}

class MyGame: Game
{
    NetworkManager networkManager;

    this(uint w, uint h, bool fullscreen, string title, string[] args)
    {
        super(w, h, fullscreen, title, args);
        networkManager = New!NetworkManager(this);
        currentScene = New!TestScene(this);
    }
}

Реализация полностью потоко-безопасна — хост и пир ENet, ассоциированные с NetworkClient, изолированы в рамках потока, и цикл enet_host_service у него тоже свой собственный.

На данный момент NetworkClient работает только со строками (как, собственно, и сам брокер сообщений). Для поддержки бинарных данных, видимо, придется чуть изменить архитектуру. Кроме того, хочется, чтобы было из коробки шифрование, так что буду копать в сторону AEAD-алгоритмов.