WebSocket client for Unity/MonoGame/Godot Mono - with no external dependencies (WebGL, Native, Android, iOS, UWP)
WebSocket client for Unity/MonoGame/Godot Mono - with no external dependencies (WebGL, Native, Android, iOS, UWP)
A simple, dependency-free WebSocket client library for Unity, MonoGame, Godot, and any .NET project.
System.Net.WebSockets)SynchronizationContextUsed in Colyseus Unity SDK.
Requires Unity 2019.1+ with .NET 4.x+ Runtime
Note: Do not copy the raw source files from this repository directly into your Unity project. The core
WebSocket.csrequires a build-time transformation to add WebGL conditional compilation guards. Use one of the install methods below instead.
Via UPM (Unity Package Manager):
https://github.com/endel/NativeWebSocket.git#upm-2If you need the previous 1.x package instead, use https://github.com/endel/NativeWebSocket.git#upm in UPM, or check out the repository sources from the 1.x branch.
Via .unitypackage:
NativeWebSocket.unitypackage from the Releases pagedotnet add package Colyseus.NativeWebSocket
dotnet add package Colyseus.NativeWebSocket.MonoGame
dotnet add package Colyseus.NativeWebSocket
…
WebGL note: Unity pauses the game loop when the browser tab loses focus, which
stops all WebSocket send/receive callbacks. To keep the connection active in the
background, set Application.runInBackground = true in your script or enable
Run In Background in Player Settings > Resolution and Presentation.
Add the WebSocketGameComponent to your game. This installs a
SynchronizationContext so all WebSocket events fire on the game thread
automatically.
…
Godot Mono has a built-in GodotSynchronizationContext, so no special
integration is needed. All WebSocket events fire on the main thread
automatically.
…
If your environment doesn't have a SynchronizationContext (e.g. a console
app), call DispatchMessageQueue() from your main loop to process events:
var ws = new WebSocket("ws://localhost:3000");
ws.OnMessage += (bytes) => Console.WriteLine("Received " + bytes.Length + " bytes");
_ = ws.Connect();
while (true)
{
ws.DispatchMessageQueue();
Thread.Sleep(16);
}
Full runnable examples are in the examples/ directory:
| Engine | Path | How to run |
|---|---|---|
| MonoGame | examples/MonoGame/ |
dotnet run --project examples/MonoGame/MonoGameExample.csproj |
| Godot | examples/Godot/ |
Open in Godot Editor (4.x+ with C#), build, and press Play |
| Unity | examples/Unity/ |
Import NativeWebSocket via UPM, add Connection.cs to a GameObject |
All examples connect to the included test server:
cd node-websocket-server
npm install
npm start
The server listens on ws://localhost:3000, sends periodic text and binary
messages, and logs anything received from the client.
new WebSocket(string url)
new WebSocket(string url, Dictionary<string, string> headers)
new WebSocket(string url, string subprotocol)
new WebSocket(string url, List<string> subprotocols)
| Event | Signature | Description |
|---|---|---|
OnOpen |
() |
Connection established |
OnMessage |
(byte[] data) |
Message received (text or binary) |
OnError |
(string errorMsg) |
Error occurred |
OnClose |
(WebSocketCloseCode code) |
Connection closed |
| Method | Description |
|---|---|
Connect() |
Connect to the server (async) |
Close(code, reason) |
Gracefully close the connection (async) |
Send(byte[]) |
Send binary data (async) |
SendText(string) |
Send text data (async) |
CancelConnection() |
Cancel a pending connection attempt |
DispatchMessageQueue() |
Manually dispatch queued events (only needed without a SynchronizationContext) |
| Property | Type | Description |
|---|---|---|
State |
WebSocketState |
Connecting, Open, Closing, or Closed |
The core library no longer depends on UnityEngine. It targets netstandard2.0 and net6.0, and works across Unity, MonoGame, Godot, and any .NET project. Unity-specific code (WebGL) has been moved to separate integration files.
MainThreadUtil, WaitForUpdate, and WaitForBackgroundThread removedThese Unity-specific classes have been removed. Event dispatching is now handled automatically via SynchronizationContext. Remove any references to these classes from your code.
// 1.x — these no longer exist in 2.x
MainThreadUtil.Instance
MainThreadUtil.synchronizationContext
new WaitForUpdate()
new WaitForBackgroundThread()
Update() dispatch loopIn 1.x, you had to call DispatchMessageQueue() every frame from Update():
// 1.x — REQUIRED in Update()
void Update() {
websocket.DispatchMessageQueue();
}
In 2.x, events are automatically dispatched to the main thread via SynchronizationContext in Unity, Godot, and MonoGame (with WebSocketGameComponent). Remove the Update() dispatch call. DispatchMessageQueue() is only needed in environments without a SynchronizationContext (e.g. console apps).
Close() accepts close code and reason// 1.x — no parameters
await websocket.Close();
// 2.x — optional close code and reason
await websocket.Close(WebSocketCloseCode code = WebSocketCloseCode.Normal, string reason = null);
Existing Close() calls without arguments still compile. However, if you implemented the IWebSocket interface directly, you must update your implementation to match the new signature.
IWebSocket interface expandedThe interface now declares methods in addition to events and state:
// 2.x interface
public interface IWebSocket {
event WebSocketOpenEventHandler OnOpen;
event WebSocketMessageEventHandler OnMessage;
event WebSocketErrorEventHandler OnError;
event WebSocketCloseEventHandler OnClose;
WebSocketState State { get; }
// New in 2.x
Task Connect();
Task Close(WebSocketCloseCode code = WebSocketCloseCode.Normal, string reason = null);
Task Send(byte[] data);
Task SendText(string message);
}
Any custom IWebSocket implementation must now include these methods.
In 1.x, you could copy NativeWebSocket/Assets/WebSocket/WebSocket.cs into your Unity project. In 2.x, the core source lives in src/NativeWebSocket/ and requires a build-time transformation to add WebGL conditional compilation guards. Use UPM or the .unitypackage instead of copying raw files.
| What changed | Action required |
|---|---|
MainThreadUtil / WaitForUpdate / WaitForBackgroundThread removed |
Delete any code using these classes |
| Automatic event dispatching | Remove DispatchMessageQueue() from Update() (Unity/Godot/MonoGame) |
Custom IWebSocket implementations |
Add Connect(), Close(), Send(), SendText() methods |
| Manual file copy installs | Switch to UPM or .unitypackage |
Big thanks to Jiri Hybek. This implementation is based on his work.
Apache 2.0
No open issues yet, or sync has not completed.