{"id":35582673,"url":"https://github.com/magithar/socketio-unity","last_synced_at":"2026-04-16T14:11:53.772Z","repository":{"id":330776735,"uuid":"1123918161","full_name":"Magithar/socketio-unity","owner":"Magithar","description":"Socket.IO v4 client for Unity (Standalone \u0026 WebGL), implemented from protocol specifications with a Unity-friendly API.","archived":false,"fork":false,"pushed_at":"2026-03-31T18:19:45.000Z","size":511,"stargazers_count":5,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-03-31T20:05:37.501Z","etag":null,"topics":["csharp","gamedev","multiplayer","networking","real-time","socketio","unity","unity3d","websoket"],"latest_commit_sha":null,"homepage":"","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Magithar.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"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,"zenodo":null,"notice":"NOTICE.md","maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-12-27T23:05:12.000Z","updated_at":"2026-03-31T18:19:49.000Z","dependencies_parsed_at":null,"dependency_job_id":"3b6bb838-9853-4745-95b8-824993fd330f","html_url":"https://github.com/Magithar/socketio-unity","commit_stats":null,"previous_names":["magithar/socketio-unity"],"tags_count":11,"template":false,"template_full_name":null,"purl":"pkg:github/Magithar/socketio-unity","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Magithar%2Fsocketio-unity","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Magithar%2Fsocketio-unity/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Magithar%2Fsocketio-unity/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Magithar%2Fsocketio-unity/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Magithar","download_url":"https://codeload.github.com/Magithar/socketio-unity/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Magithar%2Fsocketio-unity/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31326858,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-03T01:42:14.489Z","status":"online","status_checked_at":"2026-04-03T02:00:06.642Z","response_time":107,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":["csharp","gamedev","multiplayer","networking","real-time","socketio","unity","unity3d","websoket"],"created_at":"2026-01-04T21:08:05.248Z","updated_at":"2026-04-16T14:11:53.745Z","avatar_url":"https://github.com/Magithar.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cdiv align=\"center\"\u003e\n\n![Socket.IO Unity Client](Documentation%7E/banner.png)\n\n# socketio-unity\n\n**Real-time multiplayer infrastructure for Unity** — lobby systems, player synchronization, and live backend communication, all over Socket.IO v4.\n\nWebGL-ready. Production-tested. Zero paid dependencies.\n\n[![CI](https://github.com/Magithar/socketio-unity/actions/workflows/ci.yml/badge.svg)](https://github.com/Magithar/socketio-unity/actions/workflows/ci.yml)\n[![Release](https://img.shields.io/badge/release-v1.4.0-blue)](https://github.com/Magithar/socketio-unity/releases)\n[![Unity 2020.1+](https://img.shields.io/badge/Unity-2020.1%2B-black?logo=unity\u0026logoColor=white)](https://unity.com)\n[![WebGL Supported](https://img.shields.io/badge/WebGL-Supported-brightgreen)](Documentation~/WEBGL_NOTES.md)\n[![Mirror Compatible](https://img.shields.io/badge/Mirror-Compatible-black)](package/Samples~/MirrorIntegration/README.md)\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)\n\n\u003c/div\u003e\n\n---\n\n| | |\n|---|---|\n| **Get Started** | [Getting Started](Documentation~/GETTING_STARTED.md) · [Quick Start](#quick-start) · [Installation](#installation) · [Dependencies](#dependencies) |\n| **Demo** | [Live Demo](https://magithar.github.io/socketio-unity/) · [Videos](#demo) |\n| **Learn** | [API Guide](#usage) · [Architecture](#architecture) · [API Stability](API_STABILITY.md) |\n| **Samples** | [Basic Chat](#basic-chat) · [PlayerSync](#playersync) · [Lobby](#lobby) · [LiveDemo](#livedemo) · [Mirror Integration](#mirror-integration) |\n| **Platform** | [Platforms](#supported-platforms) · [WebGL](#webgl) · [Production Readiness](#production-readiness) |\n| **Tools** | [Diagnostics Overlay](#diagnostics-overlay) · [Profiler](#unity-profiler-integration) · [Packet Tracing](#packet-tracing) · [Testing](#development--testing) |\n| **Project** | [Changelog](CHANGELOG.md) · [Contributing](#contributing) · [License](#license) |\n\n---\n\n## Quick Start\n\n**1. Install via Unity Package Manager** (`Window \u003e Package Manager` → `+` → `Add package from git URL`):\n\n```\nhttps://github.com/Magithar/socketio-unity.git?path=/package\n```\n\n**2. Connect and send events:**\n\n```csharp\nvar socket = SocketIOManager.Instance.Socket;\n\nsocket.OnConnected += () =\u003e Debug.Log(\"Connected!\");\n\nsocket.On(\"chat\", msg =\u003e Debug.Log(\"Server: \" + msg));\n\nsocket.Connect(\"ws://localhost:3002\");\nsocket.Emit(\"chat\", \"Hello from Unity!\");\n```\n\n**3. Run the test server:**\n\n```bash\ncd TestServer~ \u0026\u0026 npm install \u0026\u0026 npm run start:basicchat\n```\n\nOpen the **Basic Chat** sample and press Play. → [Full guide](#basic-chat)\n\n---\n\n## Why socketio-unity?\n\nMost Unity Socket.IO clients are closed-source, incomplete, or platform-locked. This is a clean-room, open-source alternative built from the public protocol spec.\n\n| | socketio-unity | Typical Unity Asset |\n|---|---|---|\n| Open source (MIT) | **Yes** | Often closed-source |\n| Socket.IO v4 full protocol | **Yes** | Partial / outdated |\n| WebGL | **Verified** | Often broken |\n| Binary payloads | **Yes** | Limited |\n| Namespace multiplexing | **Yes** | Sometimes missing |\n| ACK callbacks with timeout | **Yes** | Partial |\n| Reconnect with backoff + jitter | **Yes** | Basic or hardcoded |\n| Unity Profiler integration | **Yes** | No |\n| CI-tested on every commit | **Yes** | Rare |\n| Mirror integration sample | **Yes** | No |\n\n**What you can build:** multiplayer lobbies, real-time player sync, WebGL browser multiplayer, chat/notification systems, mobile multiplayer, or a signaling layer for Mirror/Netcode.\n\n---\n\n## Demo\n\n**[Play Live Demo in Browser](https://magithar.github.io/socketio-unity/)** — WebGL build, no install required.\n\n\u003e The demo server spins down when idle. First load may take ~40 seconds to connect — this is expected.\n\n| Sample | Video |\n|---|---|\n| Basic Chat | [Watch on YouTube](https://youtu.be/7dU89B9O50c) |\n| Player Sync — WebGL Multiplayer | [Watch on YouTube](https://www.youtube.com/watch?v=pdLP2jB7iEE) |\n\n---\n\n## Installation\n\n### Option 1: Unity Package Manager (Recommended)\n\n1. Open Unity's Package Manager (`Window \u003e Package Manager`)\n2. Click `+` → `Add package from git URL`\n3. Enter: `https://github.com/Magithar/socketio-unity.git?path=/package`\n\n### Option 2: Manual\n\nDownload or clone this repository and copy the `package/` subdirectory into your project's `Packages/` directory (or add via `Add package from disk` → select `package/package.json`).\n\n## Dependencies\n\n| Package | Source | Purpose |\n|---|---|---|\n| **Newtonsoft.Json** | `com.unity.nuget.newtonsoft-json` | JSON serialization (built into Unity 2020.1+) |\n| **NativeWebSocket** | [endel/NativeWebSocket](https://github.com/endel/NativeWebSocket) | WebSocket transport |\n| **Mirror** *(optional)* | [MirrorNetworking/Mirror](https://github.com/MirrorNetworking/Mirror) | Required only for the Mirror Integration sample |\n\nInstall NativeWebSocket via Package Manager git URL:\n```\nhttps://github.com/endel/NativeWebSocket.git#upm\n```\n\nMirror is not required for the core package or any other sample. Install it only if you intend to use the Mirror Integration sample — via Package Manager git URL or the `.unitypackage` from the [Mirror releases page](https://github.com/MirrorNetworking/Mirror/releases).\n\n\u003e This project includes a modified `WebSocket.cs` from NativeWebSocket with domain reload safety fixes. See [NOTICE.md](NOTICE.md).\n\n---\n\n## Usage\n\n### Scene Setup\n\n1. Create an empty GameObject and attach `SocketIOManager`\n2. The singleton persists across scenes via `DontDestroyOnLoad`\n\n### Basic Connection\n\n```csharp\nvar socket = SocketIOManager.Instance.Socket;\n\nsocket.OnConnected += () =\u003e Debug.Log(\"Connected\");\nsocket.On(\"chat\", data =\u003e Debug.Log(data));\nsocket.Emit(\"chat\", \"Hello from Unity!\");\n```\n\n### Connection State\n\n```csharp\n// Read current state\nif (socket.State == ConnectionState.Connected)\n    socket.Emit(\"status\", \"online\");\n\n// React to transitions\nsocket.OnStateChanged += (ConnectionState state) =\u003e\n    Debug.Log($\"State → {state}\");\n```\n\n| State | Meaning |\n|---|---|\n| `Disconnected` | Not connected |\n| `Connecting` | Handshake in progress |\n| `Connected` | Live and operational |\n| `Reconnecting` | Auto-reconnect active |\n\n### Error Handling\n\n```csharp\nsocket.OnError += (SocketError err) =\u003e\n{\n    switch (err.Type)\n    {\n        case ErrorType.Transport:  // Network failure\n        case ErrorType.Auth:       // Authentication rejected\n        case ErrorType.Timeout:    // Server not responding\n        case ErrorType.Protocol:   // Malformed packet\n            Debug.LogError($\"{err.Type}: {err.Message}\");\n            break;\n    }\n};\n```\n\n### Namespaces\n\n```csharp\n// Public namespace\nvar publicNs = socket.Of(\"/public\");\npublicNs.OnConnected += () =\u003e Debug.Log(\"/public connected\");\n\n// Authenticated namespace\nvar admin = socket.Of(\"/admin\", new { token = \"test-secret\" });\nadmin.OnConnected += () =\u003e admin.Emit(\"ping\", null, res =\u003e Debug.Log(\"ACK: \" + res));\n```\n\nNamespaces are multiplexed over a single WebSocket and automatically reconnected after disconnects.\n\n### Binary Events\n\n```csharp\n// Receive\nsocket.On(\"file\", (byte[] data) =\u003e Debug.Log($\"Received {data.Length} bytes\"));\n\n// Send with ACK\nbyte[] payload = File.ReadAllBytes(\"data.bin\");\nsocket.Emit(\"upload\", payload, response =\u003e Debug.Log($\"Response: {response}\"));\n```\n\n### ACK Callbacks\n\n```csharp\n// With custom timeout (default 5000ms)\nsocket.Emit(\"slowOp\", data, response =\u003e\n{\n    if (response == null) Debug.LogWarning(\"ACK timed out\");\n    else Debug.Log(\"Response: \" + response);\n}, timeoutMs: 10000);\n```\n\n### Event Cleanup\n\n```csharp\nvoid OnDestroy()\n{\n    socket?.Off(\"chat\", chatHandler);\n    socket?.Off(\"file\", fileHandler);\n}\n```\n\n### Disconnect vs Shutdown\n\n| Scenario | Method |\n|---|---|\n| User logs out, may return | `Disconnect()` |\n| Switching servers | `Disconnect()` then `Connect(newUrl)` |\n| Application quitting | `Shutdown()` |\n\n### Reconnect Configuration\n\n```csharp\nsocket.ReconnectConfig = new ReconnectConfig\n{\n    initialDelay  = 1f,\n    multiplier    = 2f,\n    maxDelay      = 30f,\n    maxAttempts   = -1,      // unlimited\n    jitterPercent = 0.1f,    // prevents thundering herd\n};\n```\n\nPresets: `ReconnectConfig.Default()`, `.Aggressive()`, `.Conservative()`.\nFull details: [RECONNECT_BEHAVIOR.md](Documentation~/RECONNECT_BEHAVIOR.md)\n\n### Thread Safety\n\nAll callbacks (`OnConnected`, `OnDisconnected`, `OnError`, `On()` handlers, ACK callbacks) execute on Unity's main thread via `UnityMainThreadDispatcher`.\n\n### RTT \u0026 Throughput\n\n```csharp\nfloat rtt = socket.PingRttMs;\nfloat sent = SocketIOThroughputTracker.SentBytesPerSec;\nfloat recv = SocketIOThroughputTracker.ReceivedBytesPerSec;\n```\n\n---\n\n## Samples\n\n### Basic Chat\n\nProduction-ready \"Hello World\" — connection lifecycle, event handling, reconnection, cleanup.\n\n```csharp\nvar socket = SocketIOManager.Instance.Socket;\nsocket.OnConnected += OnConnected;\nsocket.On(\"chat\", OnChatMessage);\nsocket.Connect(\"ws://localhost:3002\");\n```\n\n[Video](https://youtu.be/7dU89B9O50c) · [Full docs](package/Samples~/BasicChat/README.md) · Import via Package Manager → Samples → \"Basic Chat\"\n\n### PlayerSync\n\nReal-time multiplayer synchronization — position sync at 20Hz, player join/leave, network interpolation, RTT display.\n\n```csharp\nrootSocket = new SocketIOClient(TransportFactoryHelper.CreateDefault());\nrootSocket.Connect(\"ws://localhost:3003\");\nvar ns = rootSocket.Of(\"/playersync\");\nns.On(\"existing_players\", (string json) =\u003e { /* spawn remote players */ });\nns.Emit(\"player_move\", JsonConvert.SerializeObject(movePacket));\n```\n\n[Video](https://www.youtube.com/watch?v=pdLP2jB7iEE) · [Full docs](package/Samples~/PlayerSync/README.md) · Import via Package Manager → Samples → \"Player Sync\"\n\n### Lobby\n\nMultiplayer lobby with host migration, session identity, reconnect grace window, and three-layer architecture (transport → state store → UI).\n\n```\nnpm run start:lobby   # http://localhost:3001\n```\n\nFeatures: room creation, join-by-code, persistent identity across reconnects, session token auth, 10-second grace window, automatic host promotion.\n\n[Full docs](package/Samples~/Lobby/README.md) · Import via Package Manager → Samples → \"Lobby\"\n\n### LiveDemo\n\nCombines Lobby and PlayerSync into a single scene — lobby room creation flows into real-time player movement via `GameOrchestrator` layer toggling.\n\n```bash\n# Single-process (recommended for deployment)\nnpm run start:livedemo     # :3000 — /lobby + /playersync\n\n# Or split servers for development\nnpm run start:lobby        # Terminal 1 — :3001\nnpm run start:playersync   # Terminal 2 — :3003\n```\n\n[Full docs](package/Samples~/LiveDemo/README.md) · Import via Package Manager → Samples → \"Live Demo\"\n\n### Mirror Integration\n\nHybrid architecture — Socket.IO handles matchmaking and backend events, Mirror handles in-scene transform sync. Editor hosts, standalone/WebGL clients connect. Local only.\n\n```bash\nnpm run start:mirror   # Port 3002 — lobby + /game namespace\n```\n\nRequires Mirror and the Lobby sample. Standalone build target recommended; WebGL works via SimpleWebTransport for local testing.\n\n[Sample docs](package/Samples~/MirrorIntegration/README.md) · [Architecture guide](package/Samples~/MirrorIntegration/MIRROR_INTEGRATION.md) · Import via Package Manager → Samples → \"Mirror Integration\"\n\n---\n\n## Architecture\n\n```mermaid\ngraph TD\n    Server[\"Socket.IO Server\"]\n\n    subgraph Transport [\"ITransport\"]\n        WS[\"WebSocketTransport\u003cbr/\u003eStandalone / Editor\"]\n        WebGL[\"WebGLWebSocketTransport\u003cbr/\u003eBrowser JS bridge\"]\n    end\n\n    subgraph Engine [\"EngineIOClient\"]\n        Handshake[\"Handshake\"]\n        Heartbeat[\"HeartbeatController\"]\n        RTT[\"PingRttTracker\"]\n    end\n\n    subgraph SocketIO [\"SocketIOClient\"]\n        NSManager[\"NamespaceManager\"]\n        NS[\"NamespaceSocket\"]\n        Reconnect[\"ReconnectController\"]\n        Binary[\"BinaryPacketAssembler\"]\n    end\n\n    Manager[\"SocketIOManager\u003cbr/\u003eUnity singleton\"]\n\n    Server -- \"WebSocket frames\" --\u003e Transport\n    Transport --\u003e Engine\n    Engine --\u003e SocketIO\n    SocketIO --\u003e Manager\n```\n\nKey principles: single WebSocket connection, namespace multiplexing, tick-driven (no background threads), `IDisposable` resource cleanup, `Off()` for leak prevention.\n\nFull architecture docs: [ARCHITECTURE.md](Documentation~/ARCHITECTURE.md)\n\n---\n\n## Supported Platforms\n\n| Platform | Status |\n|---|---|\n| Unity Editor | Supported |\n| Windows / macOS / Linux | Supported |\n| WebGL | Verified |\n| Android / iOS | Verified |\n\n| Server Version | Supported |\n|---|---|\n| Socket.IO v4.x | Yes |\n| Socket.IO v3.x / v2.x | No |\n| Engine.IO long-polling | No (intentional) |\n\nMinimum Unity version: 2019.4 LTS (core), 2020.1+ (built-in Newtonsoft.Json), 2020.2+ (Profiler Counters).\n\n## Production Readiness\n\nStable public API (frozen for v1.x), CI-validated on Unity 2022.3 LTS, 38+ protocol edge-case tests, bug regression tests, WebGL and mobile verified, configurable reconnect, zero GC allocations in hot paths, main-thread safe, domain reload safe, `IDisposable` resource management.\n\n## WebGL\n\nWebGL support is production-verified. The `SocketIOWebGL.jslib` JavaScript bridge handles WebSocket communication in browser builds. Root and custom namespaces, binary data, auth, and reconnection all work in WebGL.\n\nForce-refresh (`Cmd+Shift+R`) or use Incognito when iterating on WebGL builds to avoid cached JS/WASM issues.\n\n---\n\n## Diagnostics Overlay\n\n```csharp\nSocketIOManager.Instance.ShowDiagnostics = true;\n```\n\nShows connection state (color-coded), RTT, active namespaces, pending ACKs, and a live event log. Throughput display requires the `SOCKETIO_PROFILER_COUNTERS` define.\n\n## Unity Profiler Integration\n\nAdd `SOCKETIO_PROFILER` to Player Settings → Scripting Define Symbols.\n\n| Marker | Description |\n|---|---|\n| `SocketIO.EngineIO.Parse` | Engine.IO packet parsing |\n| `SocketIO.Event.Dispatch` | Event handler dispatch |\n| `SocketIO.Binary.Assemble` | Binary frame assembly |\n| `SocketIO.Ack.Resolve` | ACK resolution |\n| `SocketIO.Reconnect.Tick` | Reconnection tick |\n\nZero cost when define is off (~20-40ns per scope when on, 0 GC).\n\n### Profiler Counters\n\nAdd `SOCKETIO_PROFILER_COUNTERS` to Scripting Define Symbols (Unity 2020.2+).\n\nCounters: `SocketIO.Bytes Sent`, `SocketIO.Bytes Received`, `SocketIO.Packets/sec`, `SocketIO.Active Namespaces`, `SocketIO.Pending ACKs`.\n\n## Packet Tracing\n\n```csharp\nTraceConfig.Level = TraceLevel.Protocol; // None, Errors, Protocol, Verbose\n```\n\nCustom output via `ITraceSink`:\n```csharp\nSocketIOTrace.SetSink(new MyTraceSink());\n```\n\n---\n\n## Development \u0026 Testing\n\n### Test Servers\n\n```bash\ncd TestServer~ \u0026\u0026 npm install\n\nnpm run start:basicchat    # Port 3002\nnpm start                  # Port 3000 (binary/auth)\nnpm run start:playersync   # Port 3003\nnpm run start:lobby        # Port 3001\nnpm run start:livedemo     # Port 3000 (combined lobby + playersync)\nnpm run start:mirror       # Port 3002 (lobby + /game namespace for Mirror integration)\n```\n\n### Test Suite\n\n| Test | Type | Covers |\n|---|---|---|\n| `ProtocolEdgeCaseTests.cs` | Editor tool | Protocol parsing edge cases |\n| `BugRegressionTests.cs` | Runtime NUnit | Binary assembler, ACK overflow, JSON degradation |\n| `ReconnectConfigTests.cs` | Runtime NUnit | Defensive copy, factory presets |\n| `ConnectionStateTests.cs` | Runtime NUnit | State transitions, OnStateChanged, namespace reconnect |\n| `LobbyStateIntegrationTests.cs` | Runtime NUnit | State invariants, namespace timing |\n| `StressTests.cs` | EditMode NUnit | 1K events, 10MB binary, 100 ACKs, 50 reconnects |\n\n### CI\n\nGitHub Actions with [`game-ci/unity-test-runner`](https://github.com/game-ci/unity-test-runner) on every push/PR to `main`. Runs EditMode tests against Unity 2022.3 LTS. Requires `UNITY_LICENSE`, `UNITY_EMAIL`, `UNITY_PASSWORD` secrets.\n\n---\n\n## Contributing\n\nContributions welcome with one hard rule:\n\n\u003e **Clean-room only.** Do not copy or port code from the official Socket.IO JS client, any paid Unity asset, or any other existing implementation. All contributions must be original.\n\nOpen an issue first for significant changes. Include Unity version, platform, and reproduction steps in bug reports.\n\nFull guidelines: [CONTRIBUTING.md](CONTRIBUTING.md)\n\n## License\n\n[MIT](LICENSE) — free for commercial and non-commercial use.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmagithar%2Fsocketio-unity","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmagithar%2Fsocketio-unity","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmagithar%2Fsocketio-unity/lists"}