{"id":14960493,"url":"https://github.com/endel/nativewebsocket","last_synced_at":"2026-04-01T20:40:32.780Z","repository":{"id":37533270,"uuid":"200769444","full_name":"endel/NativeWebSocket","owner":"endel","description":"🔌 WebSocket client for Unity - with no external dependencies (WebGL, Native, Android, iOS, UWP)","archived":false,"fork":false,"pushed_at":"2025-03-16T01:20:48.000Z","size":107,"stargazers_count":1368,"open_issues_count":55,"forks_count":169,"subscribers_count":34,"default_branch":"master","last_synced_at":"2025-04-06T18:08:35.560Z","etag":null,"topics":["unity-asset","unity3d-plugin","webgl","websockets"],"latest_commit_sha":null,"homepage":"","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/endel.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":"endel","patreon":"endel","open_collective":null,"ko_fi":"endeld","tidelift":null,"custom":"https://www.paypal.me/endeld"}},"created_at":"2019-08-06T03:27:58.000Z","updated_at":"2025-04-05T16:31:33.000Z","dependencies_parsed_at":"2024-01-11T17:42:35.842Z","dependency_job_id":"33eda098-3d80-4e98-adab-c4d0260da9d8","html_url":"https://github.com/endel/NativeWebSocket","commit_stats":null,"previous_names":[],"tags_count":4,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/endel%2FNativeWebSocket","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/endel%2FNativeWebSocket/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/endel%2FNativeWebSocket/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/endel%2FNativeWebSocket/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/endel","download_url":"https://codeload.github.com/endel/NativeWebSocket/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248775167,"owners_count":21159565,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["unity-asset","unity3d-plugin","webgl","websockets"],"created_at":"2024-09-24T13:22:22.982Z","updated_at":"2026-04-01T20:40:32.768Z","avatar_url":"https://github.com/endel.png","language":"C#","funding_links":["https://github.com/sponsors/endel","https://patreon.com/endel","https://ko-fi.com/endeld","https://www.paypal.me/endeld"],"categories":[],"sub_categories":[],"readme":"\u003cimg src=\"Media/header.png?raw=true\" alt=\"Native WebSocket\" /\u003e\n\nA simple, dependency-free WebSocket client library for **Unity**, **MonoGame**, **Godot**, and any **.NET** project.\n\n- No external DLL's required (uses built-in `System.Net.WebSockets`)\n- WebGL/HTML5 support (Unity)\n- Supports all major build targets\n- Automatic main-thread event dispatching via `SynchronizationContext`\n- Very simple API\n\nUsed in [Colyseus Unity SDK](https://github.com/colyseus/colyseus-unity-sdk).\n\n# Installation\n\n## Unity\n\n*Requires Unity 2019.1+ with .NET 4.x+ Runtime*\n\n\u003e **Note:** Do not copy the raw source files from this repository directly into\n\u003e your Unity project. The core `WebSocket.cs` requires a build-time\n\u003e transformation to add WebGL conditional compilation guards. Use one of the\n\u003e install methods below instead.\n\n**Via UPM (Unity Package Manager):**\n1. Open Unity\n2. Open Package Manager Window\n3. Click Add Package From Git URL\n4. Enter URL: `https://github.com/endel/NativeWebSocket.git#upm-2`\n\nIf 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](https://github.com/endel/NativeWebSocket/tree/1.x).\n\n**Via .unitypackage:**\n1. Download `NativeWebSocket.unitypackage` from the [Releases](https://github.com/endel/NativeWebSocket/releases) page\n2. In Unity, go to Assets \u003e Import Package \u003e Custom Package and select the downloaded file\n\n## MonoGame / .NET\n\n```bash\ndotnet add package Colyseus.NativeWebSocket\ndotnet add package Colyseus.NativeWebSocket.MonoGame\n```\n\n## Godot (C#)\n\n```bash\ndotnet add package Colyseus.NativeWebSocket\n```\n\n# Usage\n\n## Unity\n\n```csharp\nusing UnityEngine;\nusing NativeWebSocket;\n\npublic class Connection : MonoBehaviour\n{\n    WebSocket websocket;\n\n    async void Start()\n    {\n        Application.runInBackground = true; // Recommended for WebGL\n\n        websocket = new WebSocket(\"ws://localhost:3000\");\n\n        websocket.OnOpen += () =\u003e Debug.Log(\"Connection open!\");\n        websocket.OnError += (e) =\u003e Debug.Log(\"Error! \" + e);\n        websocket.OnClose += (code) =\u003e Debug.Log(\"Connection closed!\");\n\n        websocket.OnMessage += (bytes) =\u003e\n        {\n            var message = System.Text.Encoding.UTF8.GetString(bytes);\n            Debug.Log(\"Received: \" + message);\n        };\n\n        InvokeRepeating(\"SendWebSocketMessage\", 0.0f, 0.3f);\n\n        await websocket.Connect();\n    }\n\n    async void SendWebSocketMessage()\n    {\n        if (websocket.State == WebSocketState.Open)\n        {\n            await websocket.Send(new byte[] { 10, 20, 30 });\n            await websocket.SendText(\"plain text message\");\n        }\n    }\n\n    private async void OnApplicationQuit()\n    {\n        await websocket.Close();\n    }\n}\n```\n\n**WebGL note:** Unity pauses the game loop when the browser tab loses focus, which\nstops all WebSocket send/receive callbacks. To keep the connection active in the\nbackground, set `Application.runInBackground = true` in your script or enable\n**Run In Background** in Player Settings \u003e Resolution and Presentation.\n\n## MonoGame\n\nAdd the `WebSocketGameComponent` to your game. This installs a\n`SynchronizationContext` so all WebSocket events fire on the game thread\nautomatically.\n\n```csharp\nusing System;\nusing System.Text;\nusing Microsoft.Xna.Framework;\nusing NativeWebSocket;\nusing NativeWebSocket.MonoGame;\n\npublic class Game1 : Game\n{\n    private WebSocket _websocket;\n\n    protected override void Initialize()\n    {\n        Components.Add(new WebSocketGameComponent(this));\n        base.Initialize();\n    }\n\n    protected override async void LoadContent()\n    {\n        _websocket = new WebSocket(\"ws://localhost:3000\");\n\n        _websocket.OnOpen += () =\u003e Console.WriteLine(\"Connected!\");\n        _websocket.OnError += (e) =\u003e Console.WriteLine(\"Error! \" + e);\n        _websocket.OnClose += (code) =\u003e Console.WriteLine(\"Closed: \" + code);\n\n        _websocket.OnMessage += (bytes) =\u003e\n        {\n            var message = Encoding.UTF8.GetString(bytes);\n            Console.WriteLine(\"Received: (\" + bytes.Length + \" bytes) \" + message);\n        };\n\n        await _websocket.Connect();\n    }\n\n    protected override async void OnExiting(object sender, EventArgs args)\n    {\n        if (_websocket != null)\n            await _websocket.Close();\n        base.OnExiting(sender, args);\n    }\n}\n```\n\n## Godot\n\nGodot Mono has a built-in `GodotSynchronizationContext`, so no special\nintegration is needed. All WebSocket events fire on the main thread\nautomatically.\n\n```csharp\nusing System.Text;\nusing Godot;\nusing NativeWebSocket;\n\npublic partial class WebSocketExample : Node\n{\n    private WebSocket _websocket;\n\n    public override async void _Ready()\n    {\n        _websocket = new WebSocket(\"ws://localhost:3000\");\n\n        _websocket.OnOpen += () =\u003e GD.Print(\"Connected!\");\n        _websocket.OnError += (e) =\u003e GD.Print(\"Error! \" + e);\n        _websocket.OnClose += (code) =\u003e GD.Print(\"Closed: \" + code);\n\n        _websocket.OnMessage += (bytes) =\u003e\n        {\n            var message = Encoding.UTF8.GetString(bytes);\n            GD.Print(\"Received: (\" + bytes.Length + \" bytes) \" + message);\n        };\n\n        await _websocket.Connect();\n    }\n\n    public override void _ExitTree()\n    {\n        _websocket?.Close();\n    }\n}\n```\n\n## Generic .NET (no SynchronizationContext)\n\nIf your environment doesn't have a `SynchronizationContext` (e.g. a console\napp), call `DispatchMessageQueue()` from your main loop to process events:\n\n```csharp\nvar ws = new WebSocket(\"ws://localhost:3000\");\nws.OnMessage += (bytes) =\u003e Console.WriteLine(\"Received \" + bytes.Length + \" bytes\");\n_ = ws.Connect();\n\nwhile (true)\n{\n    ws.DispatchMessageQueue();\n    Thread.Sleep(16);\n}\n```\n\n# Examples\n\nFull runnable examples are in the [`examples/`](examples/) directory:\n\n| Engine | Path | How to run |\n|--------|------|------------|\n| **MonoGame** | [`examples/MonoGame/`](examples/MonoGame/) | `dotnet run --project examples/MonoGame/MonoGameExample.csproj` |\n| **Godot** | [`examples/Godot/`](examples/Godot/) | Open in Godot Editor (4.x+ with C#), build, and press Play |\n| **Unity** | [`examples/Unity/`](examples/Unity/) | Import NativeWebSocket via UPM, add `Connection.cs` to a GameObject |\n\nAll examples connect to the included test server:\n\n```bash\ncd node-websocket-server\nnpm install\nnpm start\n```\n\nThe server listens on `ws://localhost:3000`, sends periodic text and binary\nmessages, and logs anything received from the client.\n\n# API\n\n## Constructor\n\n```csharp\nnew WebSocket(string url)\nnew WebSocket(string url, Dictionary\u003cstring, string\u003e headers)\nnew WebSocket(string url, string subprotocol)\nnew WebSocket(string url, List\u003cstring\u003e subprotocols)\n```\n\n## Events\n\n| Event | Signature | Description |\n|-------|-----------|-------------|\n| `OnOpen` | `()` | Connection established |\n| `OnMessage` | `(byte[] data)` | Message received (text or binary) |\n| `OnError` | `(string errorMsg)` | Error occurred |\n| `OnClose` | `(WebSocketCloseCode code)` | Connection closed |\n\n## Methods\n\n| Method | Description |\n|--------|-------------|\n| `Connect()` | Connect to the server (async) |\n| `Close(code, reason)` | Gracefully close the connection (async) |\n| `Send(byte[])` | Send binary data (async) |\n| `SendText(string)` | Send text data (async) |\n| `CancelConnection()` | Cancel a pending connection attempt |\n| `DispatchMessageQueue()` | Manually dispatch queued events (only needed without a `SynchronizationContext`) |\n\n## Properties\n\n| Property | Type | Description |\n|----------|------|-------------|\n| `State` | `WebSocketState` | `Connecting`, `Open`, `Closing`, or `Closed` |\n\n---\n\n# Migrating from 1.x\n\n## Breaking changes\n\n### Universal .NET library\n\nThe 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.\n\n### `MainThreadUtil`, `WaitForUpdate`, and `WaitForBackgroundThread` removed\n\nThese Unity-specific classes have been removed. Event dispatching is now handled automatically via `SynchronizationContext`. Remove any references to these classes from your code.\n\n```csharp\n// 1.x — these no longer exist in 2.x\nMainThreadUtil.Instance\nMainThreadUtil.synchronizationContext\nnew WaitForUpdate()\nnew WaitForBackgroundThread()\n```\n\n### Automatic event dispatching — no more `Update()` dispatch loop\n\nIn 1.x, you had to call `DispatchMessageQueue()` every frame from `Update()`:\n\n```csharp\n// 1.x — REQUIRED in Update()\nvoid Update() {\n    websocket.DispatchMessageQueue();\n}\n```\n\nIn 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).\n\n### `Close()` accepts close code and reason\n\n```csharp\n// 1.x — no parameters\nawait websocket.Close();\n\n// 2.x — optional close code and reason\nawait websocket.Close(WebSocketCloseCode code = WebSocketCloseCode.Normal, string reason = null);\n```\n\nExisting `Close()` calls without arguments still compile. However, if you implemented the `IWebSocket` interface directly, you must update your implementation to match the new signature.\n\n### `IWebSocket` interface expanded\n\nThe interface now declares methods in addition to events and state:\n\n```csharp\n// 2.x interface\npublic interface IWebSocket {\n    event WebSocketOpenEventHandler OnOpen;\n    event WebSocketMessageEventHandler OnMessage;\n    event WebSocketErrorEventHandler OnError;\n    event WebSocketCloseEventHandler OnClose;\n\n    WebSocketState State { get; }\n\n    // New in 2.x\n    Task Connect();\n    Task Close(WebSocketCloseCode code = WebSocketCloseCode.Normal, string reason = null);\n    Task Send(byte[] data);\n    Task SendText(string message);\n}\n```\n\nAny custom `IWebSocket` implementation must now include these methods.\n\n### Source files cannot be copied directly\n\nIn 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.\n\n## Migration checklist\n\n| What changed | Action required |\n|---|---|\n| `MainThreadUtil` / `WaitForUpdate` / `WaitForBackgroundThread` removed | Delete any code using these classes |\n| Automatic event dispatching | Remove `DispatchMessageQueue()` from `Update()` (Unity/Godot/MonoGame) |\n| Custom `IWebSocket` implementations | Add `Connect()`, `Close()`, `Send()`, `SendText()` methods |\n| Manual file copy installs | Switch to UPM or `.unitypackage` |\n\n---\n\n## Acknowledgements\n\nBig thanks to [Jiri Hybek](https://github.com/jirihybek/unity-websocket-webgl).\nThis implementation is based on his work.\n\n## License\n\nApache 2.0\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fendel%2Fnativewebsocket","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fendel%2Fnativewebsocket","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fendel%2Fnativewebsocket/lists"}