В 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-алгоритмов.