### Start Benchmark Server Source: https://github.com/endel/nativewebsocket/blob/master/benchmarks/README.md Navigate to the server directory, install dependencies, and run the server. The server listens on ws://localhost:3000 by default. ```bash cd benchmarks/server npm install node index.js ``` -------------------------------- ### Node.js Test Server Setup Source: https://context7.com/endel/nativewebsocket/llms.txt Install and start a minimal Node.js WebSocket server for local testing. This server echoes messages and sends periodic data to connected clients. ```bash cd node-websocket-server npm install npm start # Listening on http://localhost:3000 ``` -------------------------------- ### Starting the Node.js Test Server Source: https://github.com/endel/nativewebsocket/blob/master/README.md Instructions to set up and run the included Node.js test server for NativeWebSocket examples. The server listens on ws://localhost:3000. ```bash cd node-websocket-server npm install npm start ``` -------------------------------- ### Unity WebSocket Connection Example Source: https://github.com/endel/nativewebsocket/blob/master/README.md Example of establishing a WebSocket connection in Unity. Ensure Application.runInBackground is set to true for WebGL to maintain connection when the tab loses focus. Handles connection opening, errors, closing, and message reception. ```csharp using UnityEngine; using NativeWebSocket; public class Connection : MonoBehaviour { WebSocket websocket; async void Start() { Application.runInBackground = true; // Recommended for WebGL websocket = new WebSocket("ws://localhost:3000"); websocket.OnOpen += () => Debug.Log("Connection open!"); websocket.OnError += (e) => Debug.Log("Error! " + e); websocket.OnClose += (code) => Debug.Log("Connection closed!"); websocket.OnMessage += (bytes) => { var message = System.Text.Encoding.UTF8.GetString(bytes); Debug.Log("Received: " + message); }; InvokeRepeating("SendWebSocketMessage", 0.0f, 0.3f); await websocket.Connect(); } async void SendWebSocketMessage() { if (websocket.State == WebSocketState.Open) { await websocket.Send(new byte[] { 10, 20, 30 }); await websocket.SendText("plain text message"); } } private async void OnApplicationQuit() { await websocket.Close(); } } ``` -------------------------------- ### Add Godot (C#) Package Source: https://github.com/endel/nativewebsocket/blob/master/README.md Install the NativeWebSocket package for Godot projects using the dotnet CLI. ```bash dotnet add package Colyseus.NativeWebSocket ``` -------------------------------- ### Godot WebSocket Integration Source: https://github.com/endel/nativewebsocket/blob/master/README.md Example of setting up and using NativeWebSocket within a Godot C# project. Events are automatically dispatched to the main thread. ```csharp using System.Text; using Godot; using NativeWebSocket; public partial class WebSocketExample : Node { private WebSocket _websocket; public override async void _Ready() { _websocket = new WebSocket("ws://localhost:3000"); _websocket.OnOpen += () => GD.Print("Connected!"); _websocket.OnError += (e) => GD.Print("Error! " + e); _websocket.OnClose += (code) => GD.Print("Closed: " + code); _websocket.OnMessage += (bytes) => { var message = Encoding.UTF8.GetString(bytes); GD.Print("Received: (" + bytes.Length + " bytes) " + message); }; await _websocket.Connect(); } public override void _ExitTree() { _websocket?.Close(); } } ``` -------------------------------- ### Add MonoGame / .NET Package Source: https://github.com/endel/nativewebsocket/blob/master/README.md Install the NativeWebSocket package for MonoGame or general .NET projects using the dotnet CLI. ```bash dotnet add package Colyseus.NativeWebSocket dotnet add package Colyseus.NativeWebSocket.MonoGame ``` -------------------------------- ### Removed Unity-Specific Utilities (1.x) Source: https://github.com/endel/nativewebsocket/blob/master/README.md Code examples of Unity-specific classes and utilities that were removed in version 2.x of NativeWebSocket. ```csharp // 1.x — these no longer exist in 2.x MainThreadUtil.Instance MainThreadUtil.synchronizationContext new WaitForUpdate() new WaitForBackgroundThread() ``` -------------------------------- ### Deprecated 1.x Update() Dispatch Loop Source: https://github.com/endel/nativewebsocket/blob/master/README.md Example of the manual message dispatching required in the Update() method for version 1.x of NativeWebSocket. ```csharp // 1.x — REQUIRED in Update() void Update() { websocket.DispatchMessageQueue(); } ``` -------------------------------- ### Define IWebSocket Interface and NetworkManager Example Source: https://context7.com/endel/nativewebsocket/llms.txt The IWebSocket interface defines the contract for WebSocket implementations. The NetworkManager class demonstrates how to use the interface for testability by injecting a WebSocket instance. ```csharp using NativeWebSocket; // IWebSocket is the full contract for any WebSocket implementation public interface IWebSocket { event WebSocketOpenEventHandler OnOpen; // () => void event WebSocketMessageEventHandler OnMessage; // (byte[] data) => void event WebSocketErrorEventHandler OnError; // (string errorMsg) => void event WebSocketCloseEventHandler OnClose; // (WebSocketCloseCode code) => void WebSocketState State { get; } // Connecting | Open | Closing | Closed Task Connect(); Task Close(WebSocketCloseCode code = WebSocketCloseCode.Normal, string reason = null); Task Send(byte[] data); Task SendText(string message); } // Example: code against the interface for testability public class NetworkManager { private readonly IWebSocket _ws; public NetworkManager(IWebSocket ws) { _ws = ws; } public async Task StartAsync() { _ws.OnOpen += () => Console.WriteLine("Connected"); _ws.OnMessage += bytes => Console.WriteLine($"Received {bytes.Length} bytes"); _ws.OnError += msg => Console.Error.WriteLine($"Error: {msg}"); _ws.OnClose += code => Console.WriteLine($"Closed: {code}"); await _ws.Connect(); } } ``` -------------------------------- ### Close(code, reason) — Graceful Disconnect Source: https://context7.com/endel/nativewebsocket/llms.txt Performs a clean WebSocket closing handshake. Both `code` and `reason` parameters are optional. Always `await` or fire-and-forget this before destroying the owning object to avoid unclosed sockets. Examples show a normal close, a close with a specific code and reason, and closing due to a protocol violation. ```csharp using NativeWebSocket; var ws = new WebSocket("ws://localhost:3000"); await ws.Connect(); // Normal close — no reason string await ws.Close(); // Close with a specific code and reason await ws.Close(WebSocketCloseCode.Away, "user navigated away"); // Close after detecting a protocol violation ws.OnMessage += async bytes => { if (bytes.Length > 1024 * 1024) // > 1 MB await ws.Close(WebSocketCloseCode.TooBig, "payload exceeds limit"); }; ``` -------------------------------- ### Send(byte[]) — Send Binary Data Source: https://context7.com/endel/nativewebsocket/llms.txt Queues and transmits a binary WebSocket frame. If another send is in progress, the payload is enqueued and drained automatically. Returns `Task.CompletedTask` immediately if the socket is not open or the payload is empty. This example shows sending raw bytes and serialized data. ```csharp using NativeWebSocket; var ws = new WebSocket("ws://localhost:3000"); ws.OnOpen += async () => { // Send raw binary data byte[] payload = { 0x01, 0x02, 0x03, 0xFF }; await ws.Send(payload); // Send a serialized struct as bytes byte[] header = BitConverter.GetBytes(42u); // 4-byte message ID byte[] body = System.Text.Encoding.UTF8.GetBytes("hello"); byte[] packet = new byte[header.Length + body.Length]; Buffer.BlockCopy(header, 0, packet, 0, header.Length); Buffer.BlockCopy(body, 0, packet, header.Length, body.Length); await ws.Send(packet); }; _ = ws.Connect(); ``` -------------------------------- ### SendText(string) — Send Text Data Source: https://context7.com/endel/nativewebsocket/llms.txt Encodes a string as UTF-8 and transmits it as a WebSocket text frame. Uses an internal non-blocking queue to prevent concurrent calls from blocking each other or causing out-of-order delivery. Includes examples of sending plain text, JSON, and a guarded send. ```csharp using NativeWebSocket; var ws = new WebSocket("ws://localhost:3000"); ws.OnOpen += async () => { // Simple text ping await ws.SendText("ping"); // Send JSON without a serialization library string json = "{\"type\":\"join\",\"room\":\"lobby\",\"name\":\"Alice\"}"; await ws.SendText(json); // Guard: only send when open if (ws.State == WebSocketState.Open) await ws.SendText("safe message"); }; _ = ws.Connect(); ``` -------------------------------- ### Configure BenchmarkNew in Unity Source: https://github.com/endel/nativewebsocket/blob/master/benchmarks/README.md Set up the BenchmarkNew implementation in a Unity project. Copy assets, add the BenchmarkRunner component to an empty GameObject, and set implementationName to 'new' in the Inspector. ```csharp implementationName = "new"; ``` -------------------------------- ### Configure BenchmarkOld in Unity Source: https://github.com/endel/nativewebsocket/blob/master/benchmarks/README.md Set up the BenchmarkOld implementation in a Unity project. Copy assets, add the BenchmarkRunner component to an empty GameObject, and set implementationName to 'old' in the Inspector. ```csharp implementationName = "old"; ``` -------------------------------- ### WebSocket Constructor Overloads Source: https://github.com/endel/nativewebsocket/blob/master/README.md Demonstrates various ways to instantiate the WebSocket class, including specifying headers and subprotocols. ```csharp new WebSocket(string url) ``` ```csharp new WebSocket(string url, Dictionary headers) ``` ```csharp new WebSocket(string url, string subprotocol) ``` ```csharp new WebSocket(string url, List subprotocols) ``` -------------------------------- ### Run Targeted Unity Sync-Context Benchmarks Source: https://github.com/endel/nativewebsocket/blob/master/benchmarks/README.md Utilize the BenchmarkBatchRunner in Unity's batchmode to run specific benchmarks and output results to a CSV file. Configure implementation, output file, duration, and payload sizes via command-line arguments. ```bash unity -batchmode -projectPath -executeMethod BenchmarkBatchRunner.RunSyncContextBenchmarks -benchmarkImplementation old -benchmarkOutput benchmark_results.csv -benchmarkThroughputDuration 5 -benchmarkPayloadSizes 32,256,1024,8192,65536 ``` -------------------------------- ### Connect Source: https://github.com/endel/nativewebsocket/blob/master/Media/README.txt Initiates the connection to the WebSocket server. ```APIDOC ## Connect ### Description Initiates the connection to the WebSocket server. ### Method `websocket.Connect()` ``` -------------------------------- ### WebSocket Constructor Source: https://github.com/endel/nativewebsocket/blob/master/Media/README.txt Initializes a new WebSocket client instance. Use the URL of your WebSocket server as the argument. ```APIDOC ## WebSocket Constructor ### Description Initializes a new WebSocket client instance. Use the URL of your WebSocket server as the argument. ### Method `new WebSocket(string url)` ### Parameters #### Path Parameters - **url** (string) - Required - The URL of the WebSocket server. ``` -------------------------------- ### WebSocket Constructor Source: https://github.com/endel/nativewebsocket/blob/master/README.md Initializes a new WebSocket instance with the specified URL and optional headers or subprotocols. ```APIDOC ## Constructor ```csharp new WebSocket(string url) new WebSocket(string url, Dictionary headers) new WebSocket(string url, string subprotocol) new WebSocket(string url, List subprotocols) ``` ``` -------------------------------- ### Connect() — Open the WebSocket Connection Source: https://context7.com/endel/nativewebsocket/llms.txt Initiates the WebSocket handshake asynchronously. For game loops, use fire-and-forget with `_ = ws.Connect()` or `await` it in an `async void` method to avoid blocking. The `DispatchMessageQueue()` and `Thread.Sleep()` loop is necessary in console applications to process events. ```csharp using NativeWebSocket; var ws = new WebSocket("ws://localhost:3000"); ws.OnOpen += () => Console.WriteLine("Handshake complete — connection is open"); ws.OnError += e => Console.Error.WriteLine($"Connection error: {e}"); ws.OnClose += code => Console.WriteLine($"Disconnected with code: {code}"); ws.OnMessage += bytes => { var text = System.Text.Encoding.UTF8.GetString(bytes); Console.WriteLine($"Received ({bytes.Length} bytes): {text}"); }; // Fire-and-forget in a console app — Connect() blocks until the socket closes _ = ws.Connect(); // Keep the process alive; manually pump events (no SynchronizationContext in console apps) while (true) { ws.DispatchMessageQueue(); Thread.Sleep(16); // ~60 Hz } ``` -------------------------------- ### Run Console Benchmark Harness Source: https://github.com/endel/nativewebsocket/blob/master/benchmarks/README.md Execute the console runner to compare old vs new implementations without Unity. This is useful for rapid iteration on the harness itself. ```bash cd benchmarks/ConsoleRunner dotnet run -c Release ``` -------------------------------- ### Connect() — Open the Connection Source: https://context7.com/endel/nativewebsocket/llms.txt Initiates the WebSocket handshake asynchronously. This method does not return until the connection is fully closed or errors. For game loops, it's recommended to use fire-and-forget or await it in an `async void` method to avoid blocking. ```APIDOC ## `Connect()` — Open the Connection `Task Connect()` initiates the WebSocket handshake asynchronously. It does not return until the connection is fully closed (or errors). For game loops, fire-and-forget with `_ = ws.Connect()` or `await` it in an `async void` lifecycle method so it doesn't block the call site. ```csharp using NativeWebSocket; var ws = new WebSocket("ws://localhost:3000"); ws.OnOpen += () => Console.WriteLine("Handshake complete — connection is open"); ws.OnError += e => Console.Error.WriteLine($"Connection error: {e}"); ws.OnClose += code => Console.WriteLine($"Disconnected with code: {code}"); ws.OnMessage += bytes => { var text = System.Text.Encoding.UTF8.GetString(bytes); Console.WriteLine($"Received ({bytes.Length} bytes): {text}"); }; // Fire-and-forget in a console app — Connect() blocks until the socket closes _ = ws.Connect(); // Keep the process alive; manually pump events (no SynchronizationContext in console apps) while (true) { ws.DispatchMessageQueue(); Thread.Sleep(16); // ~60 Hz } ``` ``` -------------------------------- ### Project Structure Overview Source: https://github.com/endel/nativewebsocket/blob/master/benchmarks/README.md Directory structure for the NativeWebSocket project, separating the Node.js benchmark server from the C# client implementations. ```text benchmarks/ ├── server/ # Node.js WebSocket echo/flood server │ ├── package.json │ └── index.js ├── BenchmarkOld/ # Old implementation (master branch) │ └── Assets/ │ ├── WebSocket/ │ │ └── WebSocket.cs # Monolithic 848-line file from master │ └── Benchmark/ │ ├── BenchmarkRunner.cs # Orchestrator MonoBehaviour │ ├── LatencyBench.cs │ ├── ThroughputBench.cs │ ├── GCAllocBench.cs │ ├── FrameTimeBench.cs │ ├── BurstBench.cs │ ├── BenchmarkStats.cs # Percentile/stats calculator │ └── BenchmarkLogger.cs # CSV + console output ├── BenchmarkNew/ # New implementation (universal branch) │ └── Assets/ │ ├── NativeWebSocket/ │ │ ├── IWebSocket.cs │ │ ├── WebSocket.cs │ │ └── WebSocketTypes.cs │ └── Benchmark/ │ └── ... (identical scripts) └── README.md ``` -------------------------------- ### WebSocket Constructor Source: https://context7.com/endel/nativewebsocket/llms.txt Creates a new WebSocket client instance. Overloads support specifying the URL, custom HTTP headers, and subprotocols. ```APIDOC ## new WebSocket(url, [headers], [subprotocol]) ### Description Creates a new WebSocket client. Four constructor overloads are provided, covering plain URL, custom HTTP headers, a single subprotocol, and a list of subprotocols. On Unity WebGL builds the constructor registers the instance with the JavaScript JSLIB layer automatically. ### Parameters - **url** (string) - Required - The WebSocket server URL. - **headers** (Dictionary) - Optional - Custom HTTP headers for the connection (native builds only). - **subprotocol** (string or List) - Optional - The subprotocol(s) to request for the connection. ### Examples 1. **Basic Usage**: ```csharp var ws = new WebSocket("ws://localhost:3000"); ``` 2. **With Custom Headers** (native builds only): ```csharp var ws = new WebSocket("wss://api.example.com/socket", new Dictionary { { "Authorization", "Bearer my-token" }, { "X-Client-Version", "1.0.0" } }); ``` 3. **With Single Subprotocol**: ```csharp var ws = new WebSocket("wss://api.example.com/socket", "v2.chat.protocol"); ``` 4. **With Multiple Subprotocols**: ```csharp var ws = new WebSocket("wss://api.example.com/socket", new List { "v2.chat.protocol", "v1.chat.protocol" }); ``` ``` -------------------------------- ### WebSocket Methods Source: https://github.com/endel/nativewebsocket/blob/master/README.md Illustrates the core methods available for managing WebSocket connections, including connecting, closing, sending data, and dispatching messages. ```csharp Connect() ``` ```csharp Close(code, reason) ``` ```csharp Send(byte[]) ``` ```csharp SendText(string) ``` ```csharp CancelConnection() ``` ```csharp DispatchMessageQueue() ``` -------------------------------- ### Node.js Test Server Implementation Source: https://context7.com/endel/nativewebsocket/llms.txt A basic Node.js WebSocket server that sends periodic text and binary messages and logs received data. It uses the 'ws' library. ```javascript import { WebSocketServer } from 'ws'; const wss = new WebSocketServer({ server }); wss.on('connection', (ws) => { // Send "hello world!" every 100 ms const textInterval = setInterval(() => ws.send("hello world!"), 100); // Send 8 random bytes every 110 ms const binInterval = setInterval(() => ws.send(crypto.randomBytes(8).buffer), 110); ws.on('message', (data) => console.log("received:", data)); ws.on('close', () => { clearInterval(textInterval); clearInterval(binInterval); }); }); ``` -------------------------------- ### Updated Close() Method Signature (2.x) Source: https://github.com/endel/nativewebsocket/blob/master/README.md Demonstrates the updated signature for the Close() method in version 2.x, which now accepts optional close code and reason parameters. ```csharp // 1.x — no parameters await websocket.Close(); // 2.x — optional close code and reason await websocket.Close(WebSocketCloseCode code = WebSocketCloseCode.Normal, string reason = null); ``` -------------------------------- ### Unity Integration Source: https://context7.com/endel/nativewebsocket/llms.txt The standard Unity integration involves attaching a `MonoBehaviour` to a `GameObject`. Unity's `UnitySynchronizationContext` ensures that all WebSocket events are automatically dispatched to the main thread, eliminating the need for manual `Update()` polling. For WebGL builds, the `WebSocket` class is automatically replaced with a JSLIB-backed implementation. ```APIDOC ## Unity Integration — `MonoBehaviour` Usage The standard Unity integration attaches a `MonoBehaviour` to a `GameObject`. Unity's built-in `UnitySynchronizationContext` automatically dispatches all WebSocket events to the main thread. No `Update()` polling is needed. For WebGL builds, the `WebSocket` class is transparently replaced by a JSLIB-backed implementation. ```csharp using System.Text; using UnityEngine; using NativeWebSocket; public class Connection : MonoBehaviour { WebSocket websocket; async void Start() { Application.runInBackground = true; // keep alive when tab loses focus (WebGL) websocket = new WebSocket("ws://localhost:3000"); websocket.OnOpen += () => Debug.Log("Connection open!"); websocket.OnError += e => Debug.Log("Error: " + e); websocket.OnClose += code => Debug.Log("Closed: " + code); websocket.OnMessage += bytes => { Debug.Log($"Received ({bytes.Length} bytes): {Encoding.UTF8.GetString(bytes)}"); }; // Repeat every 0.3 s — safe because OnOpen fires before any sends InvokeRepeating(nameof(SendWebSocketMessage), 0.0f, 0.3f); await websocket.Connect(); // blocks until socket closes } async void SendWebSocketMessage() { if (websocket.State == WebSocketState.Open) { await websocket.Send(new byte[] { 10, 20, 30 }); await websocket.SendText("hello from Unity!"); } } async void OnApplicationQuit() { await websocket.Close(); } } ``` ``` -------------------------------- ### Unity Integration with MonoBehaviour Source: https://context7.com/endel/nativewebsocket/llms.txt Integrate NativeWebSocket into Unity by attaching a `MonoBehaviour` to a `GameObject`. Unity's `UnitySynchronizationContext` handles event dispatching to the main thread automatically, eliminating the need for manual polling. For WebGL, a JSLIB-backed implementation is used transparently. ```csharp using System.Text; using UnityEngine; using NativeWebSocket; public class Connection : MonoBehaviour { WebSocket websocket; async void Start() { Application.runInBackground = true; // keep alive when tab loses focus (WebGL) websocket = new WebSocket("ws://localhost:3000"); websocket.OnOpen += () => Debug.Log("Connection open!"); websocket.OnError += e => Debug.Log("Error: " + e); websocket.OnClose += code => Debug.Log("Closed: " + code); websocket.OnMessage += bytes => { Debug.Log($"Received ({bytes.Length} bytes): {Encoding.UTF8.GetString(bytes)}"); }; // Repeat every 0.3 s — safe because OnOpen fires before any sends InvokeRepeating(nameof(SendWebSocketMessage), 0.0f, 0.3f); await websocket.Connect(); // blocks until socket closes } async void SendWebSocketMessage() { if (websocket.State == WebSocketState.Open) { await websocket.Send(new byte[] { 10, 20, 30 }); await websocket.SendText("hello from Unity!"); } } async void OnApplicationQuit() { await websocket.Close(); } } ``` -------------------------------- ### Godot Integration with Node Source: https://context7.com/endel/nativewebsocket/llms.txt Utilize NativeWebSocket within a Godot Node. Events are automatically handled on the main thread due to Godot's SynchronizationContext. Ensure the socket is closed in _ExitTree. ```csharp using System.Text; using Godot; using NativeWebSocket; public partial class WebSocketExample : Node { private WebSocket _websocket; private double _sendTimer; public override async void _Ready() { _websocket = new WebSocket("ws://localhost:3000"); _websocket.OnOpen += () => GD.Print("Connected!"); _websocket.OnError += e => GD.Print("Error: " + e); _websocket.OnClose += code => GD.Print("Closed: " + code); _websocket.OnMessage += bytes => { GD.Print($"Received ({bytes.Length} bytes): {Encoding.UTF8.GetString(bytes)}"); }; await _websocket.Connect(); } public override async void _Process(double delta) { if (_websocket?.State == WebSocketState.Open) { _sendTimer += delta; if (_sendTimer >= 0.3) { _sendTimer = 0; await _websocket.Send(new byte[] { 10, 20, 30 }); await _websocket.SendText("hello from Godot!"); } } } public override void _ExitTree() { _websocket?.Close(); } } ``` -------------------------------- ### OnOpen Event Source: https://github.com/endel/nativewebsocket/blob/master/Media/README.txt An event that triggers when a connection to the WebSocket server has been successfully established. ```APIDOC ## OnOpen Event ### Description An event that triggers when a connection to the WebSocket server has been successfully established. ### Event Signature `websocket.OnOpen += () => {}` ``` -------------------------------- ### Generic .NET WebSocket with Manual Dispatch Source: https://github.com/endel/nativewebsocket/blob/master/README.md Usage of NativeWebSocket in a generic .NET environment (e.g., console app) where a SynchronizationContext is not available. Requires manual dispatching of messages. ```csharp 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); } ``` -------------------------------- ### WebSocket State Property Source: https://github.com/endel/nativewebsocket/blob/master/README.md Shows how to check the current state of the WebSocket connection. ```csharp State ``` -------------------------------- ### Aggregate and Compare CSV Results Source: https://github.com/endel/nativewebsocket/blob/master/benchmarks/README.md Use the Python script to compare results from multiple CSV benchmark runs. Specify baseline and candidate implementations. ```python python3 benchmarks/compare_results.py \ /path/to/benchmark_old_sync.csv \ /path/to/benchmark_old_sync_2.csv \ /path/to/benchmark_new_sync.csv \ /path/to/benchmark_new_sync_2.csv \ --baseline old \ --candidate new ``` -------------------------------- ### IWebSocket Interface Methods Source: https://github.com/endel/nativewebsocket/blob/master/README.md The IWebSocket interface provides methods for managing WebSocket connections. These include initiating a connection, closing a connection with an optional reason and code, sending binary data, and sending text data. ```APIDOC ## `IWebSocket` Interface Methods ### Description This section details the methods available on the `IWebSocket` interface for interacting with WebSocket connections. ### Methods - **Connect()** - **Description**: Initiates a WebSocket connection. - **Signature**: `Task Connect()` - **Close(WebSocketCloseCode code = WebSocketCloseCode.Normal, string reason = null)** - **Description**: Closes the WebSocket connection. - **Parameters**: - `code` (WebSocketCloseCode): The close code. Defaults to `WebSocketCloseCode.Normal`. - `reason` (string): The reason for closing. Defaults to null. - **Signature**: `Task Close(WebSocketCloseCode code = WebSocketCloseCode.Normal, string reason = null)` - **Send(byte[] data)** - **Description**: Sends binary data over the WebSocket connection. - **Parameters**: - `data` (byte[]): The binary data to send. - **Signature**: `Task Send(byte[] data)` - **SendText(string message)** - **Description**: Sends text data over the WebSocket connection. - **Parameters**: - `message` (string): The text message to send. - **Signature**: `Task SendText(string message)` ``` -------------------------------- ### DispatchMessageQueue() Source: https://context7.com/endel/nativewebsocket/llms.txt Processes all queued callbacks synchronously on the calling thread. This is essential in environments lacking a SynchronizationContext, such as plain console applications or unit tests. It is not necessary in environments like Unity, Godot, or MonoGame when using WebSocketGameComponent. ```APIDOC ## `DispatchMessageQueue()` — Manual Event Pump `void DispatchMessageQueue()` processes all queued `OnMessage`, `OnOpen`, `OnError`, and `OnClose` callbacks synchronously on the calling thread. Only required in environments that have no `SynchronizationContext` (plain console apps, unit tests). In Unity, Godot, and MonoGame with `WebSocketGameComponent` this method is unnecessary. ```csharp using System.Threading; using NativeWebSocket; var ws = new WebSocket("ws://localhost:3000"); ws.OnMessage += bytes => Console.WriteLine($"[main thread] {bytes.Length} bytes"); ws.OnClose += code => Console.WriteLine($"[main thread] closed: {code}"); _ = ws.Connect(); // Poll at ~60 Hz — all callbacks fire on this thread var cts = new CancellationTokenSource(); while (!cts.Token.IsCancellationRequested) { ws.DispatchMessageQueue(); Thread.Sleep(16); } ``` ``` -------------------------------- ### WebSocket Methods Source: https://github.com/endel/nativewebsocket/blob/master/README.md Provides methods for managing the WebSocket connection and sending data. ```APIDOC ## Methods | 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`) ``` -------------------------------- ### Node.js WebSocket Server Commands Source: https://github.com/endel/nativewebsocket/blob/master/benchmarks/README.md Commands to interact with the Node.js WebSocket echo/flood server for benchmarking. Used to control message flooding and traffic sinking. ```text flood:: flood_continuous: flood_stop sink:start: burst:: ``` -------------------------------- ### WebSocket Properties Source: https://github.com/endel/nativewebsocket/blob/master/README.md Exposes the current state of the WebSocket connection. ```APIDOC ## Properties | Property | Type | Description | |----------|------|-------------| | `State` | `WebSocketState` | `Connecting`, `Open`, `Closing`, or `Closed` ``` -------------------------------- ### IWebSocket Interface in NativeWebSocket 2.x Source: https://github.com/endel/nativewebsocket/blob/master/README.md This C# interface defines the contract for WebSocket implementations in version 2.x. Custom implementations must now include Connect(), Close(), Send(), and SendText() methods. ```csharp 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); } ``` -------------------------------- ### Manually Dispatch WebSocket Messages Source: https://context7.com/endel/nativewebsocket/llms.txt Use `DispatchMessageQueue()` in environments without a `SynchronizationContext` to process callbacks synchronously. This is essential for plain console applications and unit tests. ```csharp using System.Threading; using NativeWebSocket; var ws = new WebSocket("ws://localhost:3000"); ws.OnMessage += bytes => Console.WriteLine($"[main thread] {bytes.Length} bytes"); ws.OnClose += code => Console.WriteLine($"[main thread] closed: {code}"); _ = ws.Connect(); // Poll at ~60 Hz — all callbacks fire on this thread var cts = new CancellationTokenSource(); while (!cts.Token.IsCancellationRequested) { ws.DispatchMessageQueue(); Thread.Sleep(16); } ``` -------------------------------- ### Send Binary Message Source: https://github.com/endel/nativewebsocket/blob/master/Media/README.txt Sends a binary message to the connected WebSocket server. ```APIDOC ## Send Binary Message ### Description Sends a binary message to the connected WebSocket server. ### Method `websocket.Send(byte[] bytes)` ### Parameters #### Request Body - **bytes** (byte[]) - Required - The binary data to send. ``` -------------------------------- ### State Property Source: https://github.com/endel/nativewebsocket/blob/master/Media/README.txt Retrieves the current state of the WebSocket connection. ```APIDOC ## State Property ### Description Contains the current state of the WebSocket connection. Can be one of the following values: `WebSocketState.Connecting`, `WebSocketState.Open`, `WebSocketState.Closing`, `WebSocketState.Closed`. ### Property `websocket.State` ### Return Value - **WebSocketState** - The current state of the connection. ``` -------------------------------- ### MonoGame WebSocket Integration Source: https://github.com/endel/nativewebsocket/blob/master/README.md Integrates NativeWebSocket into a MonoGame application by adding a WebSocketGameComponent. This ensures all WebSocket events are dispatched on the game thread automatically. Handles connection, errors, closing, and message reception. ```csharp using System; using System.Text; using Microsoft.Xna.Framework; using NativeWebSocket; using NativeWebSocket.MonoGame; public class Game1 : Game { private WebSocket _websocket; protected override void Initialize() { Components.Add(new WebSocketGameComponent(this)); base.Initialize(); } protected override async void LoadContent() { _websocket = new WebSocket("ws://localhost:3000"); _websocket.OnOpen += () => Console.WriteLine("Connected!"); _websocket.OnError += (e) => Console.WriteLine("Error! " + e); _websocket.OnClose += (code) => Console.WriteLine("Closed: " + code); _websocket.OnMessage += (bytes) => { var message = Encoding.UTF8.GetString(bytes); Console.WriteLine("Received: (" + bytes.Length + " bytes) " + message); }; await _websocket.Connect(); } protected override async void OnExiting(object sender, EventArgs args) { if (_websocket != null) await _websocket.Close(); base.OnExiting(sender, args); } } ``` -------------------------------- ### Close(code, reason) — Graceful Disconnect Source: https://context7.com/endel/nativewebsocket/llms.txt Performs a clean WebSocket closing handshake. Both parameters (code and reason) are optional. It's always recommended to await or fire-and-forget this method before destroying the owning object to prevent unclosed sockets. ```APIDOC ## `Close(code, reason)` — Graceful Disconnect `Task Close(WebSocketCloseCode code, string reason)` performs a clean WebSocket closing handshake. Both parameters are optional (default: `Normal`, no reason). Always await or fire-and-forget this before destroying the owning object to avoid unclosed sockets. ```csharp using NativeWebSocket; var ws = new WebSocket("ws://localhost:3000"); await ws.Connect(); // Normal close — no reason string await ws.Close(); // Close with a specific code and reason await ws.Close(WebSocketCloseCode.Away, "user navigated away"); // Close after detecting a protocol violation ws.OnMessage += async bytes => { if (bytes.Length > 1024 * 1024) // > 1 MB await ws.Close(WebSocketCloseCode.TooBig, "payload exceeds limit"); }; ``` ``` -------------------------------- ### IWebSocket Interface Source: https://context7.com/endel/nativewebsocket/llms.txt The IWebSocket interface defines the contract for all WebSocket implementations, including events for connection status and messages, a state property, and methods for connecting, closing, and sending data. ```APIDOC ## IWebSocket Interface ### Description The `IWebSocket` interface defines the complete contract implemented by both the native .NET `WebSocket` class and the Unity WebGL `WebSocket` class. It declares four events, one state property, and four async methods, enabling dependency injection and mocking in tests. ### Events - **OnOpen**: `WebSocketOpenEventHandler` - Fired when the WebSocket connection is successfully opened. - **OnMessage**: `WebSocketMessageEventHandler` - Fired when a message is received. The event handler receives `byte[] data`. - **OnError**: `WebSocketErrorEventHandler` - Fired when an error occurs. The event handler receives `string errorMsg`. - **OnClose**: `WebSocketCloseEventHandler` - Fired when the WebSocket connection is closed. The event handler receives `WebSocketCloseCode code`. ### Properties - **State**: `WebSocketState` - Represents the current state of the WebSocket connection (Connecting, Open, Closing, Closed). ### Methods - **Connect()**: `Task` - Asynchronously establishes a connection to the WebSocket server. - **Close(WebSocketCloseCode code = WebSocketCloseCode.Normal, string reason = null)**: `Task` - Asynchronously closes the WebSocket connection with an optional reason. - **Send(byte[] data)**: `Task` - Asynchronously sends binary data over the WebSocket connection. - **SendText(string message)**: `Task` - Asynchronously sends a text message over the WebSocket connection. ``` -------------------------------- ### WebSocketState Source: https://context7.com/endel/nativewebsocket/llms.txt The `State` property provides the current connection status as a `WebSocketState` enum value. It is recommended to check this property before sending data to prevent no-operation calls or exceptions. For WebGL builds, this state is synchronized with the JavaScript `readyState` through JSLIB interop. ```APIDOC ## `WebSocketState` — Connection State Property The `State` property returns the current `WebSocketState` enum value. Always check it before sending to avoid no-op calls or exceptions. On WebGL the state is read from the JavaScript `readyState` via JSLIB interop. ```csharp using NativeWebSocket; var ws = new WebSocket("ws://localhost:3000"); _ = ws.Connect(); // Poll state externally Console.WriteLine(ws.State); // WebSocketState.Connecting // Guard sends with State check async Task TrySendAsync(WebSocket socket, string message) { switch (socket.State) { case WebSocketState.Open: await socket.SendText(message); break; case WebSocketState.Connecting: Console.WriteLine("Still connecting — message dropped"); break; case WebSocketState.Closing: case WebSocketState.Closed: Console.WriteLine("Socket is closed — reconnect first"); break; } } ``` ``` -------------------------------- ### Check WebSocket Connection State Source: https://context7.com/endel/nativewebsocket/llms.txt Always check the `State` property before sending data to prevent no-op calls or exceptions. On WebGL, the state is synchronized with JavaScript's `readyState`. ```csharp using NativeWebSocket; var ws = new WebSocket("ws://localhost:3000"); _ = ws.Connect(); // Poll state externally Console.WriteLine(ws.State); // WebSocketState.Connecting // Guard sends with State check async Task TrySendAsync(WebSocket socket, string message) { switch (socket.State) { case WebSocketState.Open: await socket.SendText(message); break; case WebSocketState.Connecting: Console.WriteLine("Still connecting — message dropped"); break; case WebSocketState.Closing: case WebSocketState.Closed: Console.WriteLine("Socket is closed — reconnect first"); break; } } ``` -------------------------------- ### Send(byte[]) — Send Binary Data Source: https://context7.com/endel/nativewebsocket/llms.txt Queues and transmits a binary WebSocket frame. If another send is already in flight, the payload is enqueued and drained automatically. Returns `Task.CompletedTask` immediately if the socket is not open or the payload is empty. ```APIDOC ## `Send(byte[])` — Send Binary Data `Task Send(byte[] data)` queues and transmits a binary WebSocket frame. If another send is already in flight the payload is enqueued and drained automatically with no dropped messages. Returns `Task.CompletedTask` immediately when the socket is not open or the payload is empty. ```csharp using NativeWebSocket; var ws = new WebSocket("ws://localhost:3000"); ws.OnOpen += async () => { // Send raw binary data byte[] payload = { 0x01, 0x02, 0x03, 0xFF }; await ws.Send(payload); // Send a serialized struct as bytes byte[] header = BitConverter.GetBytes(42u); // 4-byte message ID byte[] body = System.Text.Encoding.UTF8.GetBytes("hello"); byte[] packet = new byte[header.Length + body.Length]; Buffer.BlockCopy(header, 0, packet, 0, header.Length); Buffer.BlockCopy(body, 0, packet, header.Length, body.Length); await ws.Send(packet); }; _ = ws.Connect(); ``` ``` -------------------------------- ### MonoGame Integration with WebSocketGameComponent Source: https://context7.com/endel/nativewebsocket/llms.txt Use WebSocketGameComponent to ensure WebSocket events are handled on the game thread. Add it to your game's components before creating any WebSocket instances. ```csharp using System; using System.Text; using Microsoft.Xna.Framework; using NativeWebSocket; using NativeWebSocket.MonoGame; public class Game1 : Game { private WebSocket _websocket; private float _sendTimer; protected override void Initialize() { // Must be added before any WebSocket is created Components.Add(new WebSocketGameComponent(this)); base.Initialize(); } protected override async void LoadContent() { _websocket = new WebSocket("ws://localhost:3000"); _websocket.OnOpen += () => Console.WriteLine("Connected!"); _websocket.OnError += e => Console.WriteLine("Error: " + e); _websocket.OnClose += code => Console.WriteLine("Closed: " + code); _websocket.OnMessage += bytes => { Console.WriteLine($"Received ({bytes.Length} bytes): {Encoding.UTF8.GetString(bytes)}"); }; await _websocket.Connect(); } protected override async void Update(GameTime gameTime) { if (_websocket?.State == WebSocketState.Open) { _sendTimer += (float)gameTime.ElapsedGameTime.TotalSeconds; if (_sendTimer >= 0.3f) { _sendTimer = 0; await _websocket.Send(new byte[] { 10, 20, 30 }); await _websocket.SendText("hello from MonoGame!"); } } base.Update(gameTime); } protected override async void OnExiting(object sender, EventArgs args) { if (_websocket != null) await _websocket.Close(); base.OnExiting(sender, args); } } ``` -------------------------------- ### WebSocket Events Source: https://github.com/endel/nativewebsocket/blob/master/README.md Defines the events that can be subscribed to for WebSocket communication. ```APIDOC ## Events | Event | Signature | |-------|-----------| | `OnOpen` | `()` | | `OnMessage` | `(byte[] data)` | | `OnError` | `(string errorMsg)` | | `OnClose` | `(WebSocketCloseCode code)` | ### Description - `OnOpen`: Triggered when the connection is successfully established. - `OnMessage`: Triggered when a message (text or binary) is received. - `OnError`: Triggered when an error occurs during the WebSocket communication. - `OnClose`: Triggered when the WebSocket connection is closed. ``` -------------------------------- ### Close Source: https://github.com/endel/nativewebsocket/blob/master/Media/README.txt Forcefully closes the WebSocket connection with the server. It is recommended to call this when quitting the application. ```APIDOC ## Close ### Description Forcefully closes the WebSocket connection with the server. Make sure to call `websocket.Close()` when quitting your application (e.g., in `OnApplicationQuit`). ### Method `websocket.Close()` ``` -------------------------------- ### OnMessage Event Source: https://github.com/endel/nativewebsocket/blob/master/Media/README.txt An event that triggers whenever a message is received from the server. The message is provided as a byte array. ```APIDOC ## OnMessage Event ### Description An event that triggers whenever a message is received from the server. The message is provided as a byte array. To parse string messages, use `System.Text.Encoding.UTF8.GetString(bytes)`. ### Event Signature `websocket.OnMessage += (byte[] bytes) => {}` ``` -------------------------------- ### SendText(string) — Send Text Data Source: https://context7.com/endel/nativewebsocket/llms.txt Encodes the string as UTF-8 and transmits it as a WebSocket text frame. Uses an internal non-blocking queue to prevent concurrent calls from blocking each other or causing out-of-order delivery. ```APIDOC ## `SendText(string)` — Send Text Data `Task SendText(string message)` encodes the string as UTF-8 and transmits it as a WebSocket text frame. Like `Send`, it uses an internal non-blocking queue so concurrent calls never block each other or cause out-of-order delivery. ```csharp using NativeWebSocket; var ws = new WebSocket("ws://localhost:3000"); ws.OnOpen += async () => { // Simple text ping await ws.SendText("ping"); // Send JSON without a serialization library string json = "{\"type\":\"join\",\"room\":\"lobby\",\"name\":\"Alice\"}"; await ws.SendText(json); // Guard: only send when open if (ws.State == WebSocketState.Open) await ws.SendText("safe message"); }; _ = ws.Connect(); ``` ``` -------------------------------- ### CancelConnection() — Abort a Pending Connect Source: https://context7.com/endel/nativewebsocket/llms.txt Cancels an in-progress connection attempt by triggering the internal `CancellationTokenSource`. On WebGL, it closes the socket with code `Abnormal` if the socket happens to be open. This is useful when the user navigates away before the handshake completes. ```APIDOC ## `CancelConnection()` — Abort a Pending Connect `void CancelConnection()` cancels an in-progress connection attempt by triggering the internal `CancellationTokenSource`. On WebGL it closes the socket with code `Abnormal` if the socket happens to be open. Useful when the user navigates away before the handshake completes. ```csharp using NativeWebSocket; var ws = new WebSocket("wss://slow.example.com/socket"); // Start connecting without awaiting _ = ws.Connect(); // Cancel if still connecting after 5 seconds await Task.Delay(5000); if (ws.State == WebSocketState.Connecting) { ws.CancelConnection(); Console.WriteLine("Connection attempt timed out and was cancelled."); } ``` ``` -------------------------------- ### CancelConnection() — Abort a Pending Connect Source: https://context7.com/endel/nativewebsocket/llms.txt Cancels an in-progress connection attempt by triggering the internal `CancellationTokenSource`. On WebGL, it closes the socket with code `Abnormal` if the socket happens to be open. This is useful when the user navigates away before the handshake completes. ```csharp using NativeWebSocket; var ws = new WebSocket("wss://slow.example.com/socket"); // Start connecting without awaiting _ = ws.Connect(); // Cancel if still connecting after 5 seconds await Task.Delay(5000); if (ws.State == WebSocketState.Connecting) { ws.CancelConnection(); Console.WriteLine("Connection attempt timed out and was cancelled."); } ``` -------------------------------- ### Handle WebSocket Close Codes Source: https://context7.com/endel/nativewebsocket/llms.txt Use the `WebSocketCloseCode` enum to interpret standard RFC 6455 close codes received in the `OnClose` event or passed to `Close()`. `WebSocketHelpers.ParseCloseCodeEnum()` can convert raw integer codes. ```csharp using NativeWebSocket; var ws = new WebSocket("ws://localhost:3000"); ws.OnClose += code => { switch (code) { case WebSocketCloseCode.Normal: Console.WriteLine("Clean disconnect"); break; case WebSocketCloseCode.Away: Console.WriteLine("Remote endpoint going away"); break; case WebSocketCloseCode.ProtocolError: Console.WriteLine("Protocol error — check handshake"); break; case WebSocketCloseCode.Abnormal: Console.WriteLine("Connection lost unexpectedly — schedule reconnect"); break; case WebSocketCloseCode.ServerError: Console.WriteLine("Internal server error"); break; default: Console.WriteLine($"Closed with code: {(int)code}"); break; } }; // Manual parse of a raw code var parsed = WebSocketHelpers.ParseCloseCodeEnum(1008); // PolicyViolation Console.WriteLine(parsed); // PolicyViolation ``` -------------------------------- ### Send Text Message Source: https://github.com/endel/nativewebsocket/blob/master/Media/README.txt Sends a text message to the connected WebSocket server. ```APIDOC ## Send Text Message ### Description Sends a text message to the connected WebSocket server. ### Method `websocket.SendText(string message)` ### Parameters #### Request Body - **message** (string) - Required - The text message to send. ``` -------------------------------- ### OnClose Event Source: https://github.com/endel/nativewebsocket/blob/master/Media/README.txt An event that triggers when the WebSocket connection is closed. It provides a close code. ```APIDOC ## OnClose Event ### Description An event that triggers when the WebSocket connection is closed. It provides a close code. ### Event Signature `websocket.OnClose += (int code) => {}` ### Parameters #### Event Arguments - **code** (int) - The close code indicating the reason for closure. ``` -------------------------------- ### OnError Event Source: https://github.com/endel/nativewebsocket/blob/master/Media/README.txt An event that triggers when an error occurs with the WebSocket connection. ```APIDOC ## OnError Event ### Description An event that triggers when an error occurs with the WebSocket connection. ### Event Signature `websocket.OnError += (string message) => {}` ### Parameters #### Event Arguments - **message** (string) - A message describing the error. ```