High-performance WebSocket plugin for Unreal Engine, powered by Rust.
β οΈ Note: Currently only tested on Windows. Other platforms (Linux, macOS) may work but are not yet verified.
Unreal Engine's built-in WebSocketNetworking plugin has significant limitations:
-
No Subprotocol Support -
IWebSocketServer::Init()doesn't accept subprotocol parameters, making it incompatible with protocols like MCP (Model Context Protocol) that require specific subprotocols. -
No Actual Port Retrieval -
IWebSocketServersupports ephemeral port (port 0), but provides no API to retrieve the actual assigned port after binding. See related PR.
Why rust? Honestly, I just don't want to write a single extra line of C++.
Dwebble provides a clean, standalone WebSocket server implementation using Rust's excellent async ecosystem:
- tokio - Industry-standard async runtime
- tungstenite - Native Rust WebSocket implementation
- rustls - Modern TLS implementation (no OpenSSL dependency)
- β Subprotocol Support - Full WebSocket subprotocol negotiation
- β Native TLS - Built-in TLS with rustls (ring crypto)
- β Cross-Platform - Windows x64/ARM64 support
- β Zero UE Dependencies β Standalone, doesn't interfere with existing networking
- β High Performance β Rust's zero-cost abstractions and tokio's efficient async I/O
- β Simple API - Clean C++ interface with UE-friendly types
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Unreal Engine β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β DwebbleWebSocket Module (C++) β
β βββ Dwebble::WebSocket::IServer β
β βββ Dwebble::WebSocket::FServerConfig β
β βββ Dwebble::WebSocket::FEvent β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β FFI Layer (C ABI) β
β βββ dwebble_rws.dll / dwebble_rws.dll.lib β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β Rust Core (dwebble-rws) β
β βββ tokio (async runtime) β
β βββ tokio-tungstenite (WebSocket) β
β βββ tokio-rustls (TLS) β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
#include "WebSocketServer.h"
// Create server configuration
Dwebble::WebSocket::FServerConfig Config;
Config.Port = 8080; // Use 0 for auto-assign
Config.BindAddress = TEXT("127.0.0.1");
Config.Subprotocols = { TEXT("mcp") }; // Optional subprotocols
// Create and start server
TSharedPtr<Dwebble::WebSocket::IServer> Server = Dwebble::WebSocket::IServer::Create(Config);
Server->Start();
// Get actual port (useful when Port = 0)
int32 ActualPort = Server->GetPort();
UE_LOG(LogTemp, Log, TEXT("Server listening on %s"), *Server->Info());// In your Tick function
void UMySubsystem::Tick(float DeltaTime)
{
if (!Server || !Server->IsRunning()) return;
Dwebble::WebSocket::FEvent Event;
while (Server->PollEvent(Event))
{
switch (Event.EventType)
{
case Dwebble::WebSocket::EEventType::ClientConnected:
UE_LOG(LogTemp, Log, TEXT("Client connected: %llu"), Event.ConnectionId);
break;
case Dwebble::WebSocket::EEventType::ClientDisconnected:
UE_LOG(LogTemp, Log, TEXT("Client disconnected: %llu"), Event.ConnectionId);
break;
case Dwebble::WebSocket::EEventType::MessageReceived:
HandleMessage(Event.ConnectionId, Event.Data);
break;
case Dwebble::WebSocket::EEventType::Error:
UE_LOG(LogTemp, Error, TEXT("Error: %s"), *Event.ErrorMessage);
break;
}
}
}// Send binary data
TArray<uint8> BinaryData = /* ... */;
Server->Send(ConnectionId, BinaryData);
// Send text
Server->SendText(ConnectionId, TEXT("Hello, Client!"));
// Disconnect a client
Server->Disconnect(ConnectionId);Requires:
- Rust toolchain (rustup)
- cargo-make (
cargo install cargo-make)
cd Source/dwebble-rws
# Debug build
cargo make dev
# Release build
cargo make release
# Cross-compile for ARM64 Windows
cargo make release -e TARGET=aarch64-pc-windows-msvcThe build script automatically copies the DLL to Binaries/Win64/.
In your module's Build.cs:
PublicDependencyModuleNames.AddRange(new string[] {
"DwebbleWebSocket"
});Copyright 2026 tarnishablec. All Rights Reserved.