### WatsonTcp Server Setup and Basic Operations (C#) Source: https://github.com/dotnet/watsontcp/blob/master/README.md Illustrates the setup of a WatsonTcp server, including event subscriptions for client connections, disconnections, and message reception. It also shows how to perform basic server operations like listing clients, sending messages, and sending messages with metadata. The example includes handling synchronous requests and responses. ```csharp using WatsonTcp; using System.Collections.Generic; using System.Text; using System.Threading.Tasks; static void Main(string[] args) { WatsonTcpServer server = new WatsonTcpServer("127.0.0.1", 9000); server.Events.ClientConnected += ClientConnected; server.Events.ClientDisconnected += ClientDisconnected; server.Events.MessageReceived += MessageReceived; server.Callbacks.SyncRequestReceivedAsync = SyncRequestReceived; server.Start(); // list clients IEnumerable clients = server.ListClients(); // send a message // await server.SendAsync([guid], "Hello, client!"); // Replace [guid] with actual client GUID // send a message with metadata Dictionary md = new Dictionary(); md.Add("foo", "bar"); // await server.SendAsync([guid], "Hello, client! Here's some metadata!", md); // Replace [guid] with actual client GUID // send and wait for a response try { // SyncResponse resp = await server.SendAndWaitAsync( // [guid], // 5000, // "Hey, say hello back within 5 seconds!"); // Replace [guid] with actual client GUID // Console.WriteLine("My friend says: " + Encoding.UTF8.GetString(resp.Data)); } catch (TimeoutException) { Console.WriteLine("Too slow..."); } } static void ClientConnected(object sender, ConnectionEventArgs args) { Console.WriteLine("Client connected: " + args.Client.ToString()); } static void ClientDisconnected(object sender, DisconnectionEventArgs args) { Console.WriteLine( "Client disconnected: " + args.Client.ToString() + ": " + args.Reason.ToString()); } static void MessageReceived(object sender, MessageReceivedEventArgs args) { Console.WriteLine( "Message from " + args.Client.ToString() + ": " + Encoding.UTF8.GetString(args.Data)); } static async Task SyncRequestReceived(SyncRequest req) { return new SyncResponse(req, "Hello back at you!"); } ``` -------------------------------- ### Create and Configure WatsonTcp Server in C# Source: https://context7.com/dotnet/watsontcp/llms.txt This snippet demonstrates how to create and configure a WatsonTcp server. It covers setting up the server with or without SSL, configuring debug messages and logging, and wiring up event handlers for client connections, disconnections, and message reception. The server is then started to listen for incoming connections. ```csharp using System; using System.Text; using System.Threading.Tasks; using WatsonTcp; // Create server without SSL WatsonTcpServer server = new WatsonTcpServer("127.0.0.1", 9000); // Or with SSL // WatsonTcpServer server = new WatsonTcpServer("127.0.0.1", 9000, "test.pfx", "password"); // server.Settings.AcceptInvalidCertificates = true; // server.Settings.MutuallyAuthenticate = true; // Configure settings server.Settings.DebugMessages = true; server.Settings.Logger = (severity, msg) => Console.WriteLine($"[{severity}] {msg}"); server.Settings.NoDelay = true; // Wire up event handlers server.Events.ClientConnected += (sender, args) => { Console.WriteLine($"Client connected: {args.Client.Guid} from {args.Client.IpPort}"); }; server.Events.ClientDisconnected += (sender, args) => { Console.WriteLine($"Client disconnected: {args.Client.Guid}, Reason: {args.Reason}"); }; server.Events.MessageReceived += (sender, args) => { Console.WriteLine($"Message from {args.Client.Guid}: {Encoding.UTF8.GetString(args.Data)}"); }; // Start listening server.Start(); Console.WriteLine("Server started on port 9000"); ``` -------------------------------- ### Create and Connect WatsonTcp Client in C# Source: https://context7.com/dotnet/watsontcp/llms.txt This snippet shows how to initialize and connect a WatsonTcp client to a server. It includes options for SSL configuration and setting a custom client GUID. Event handlers for server connection, disconnection, and message reception are demonstrated. The client then attempts to establish a connection to the specified server. ```csharp using System; using System.Text; using System.Threading.Tasks; using WatsonTcp; // Create client without SSL WatsonTcpClient client = new WatsonTcpClient("127.0.0.1", 9000); // Or with SSL // WatsonTcpClient client = new WatsonTcpClient("127.0.0.1", 9000, "test.pfx", "password"); // client.Settings.AcceptInvalidCertificates = true; // client.Settings.MutuallyAuthenticate = true; // Optionally set a custom GUID before connecting client.Settings.Guid = Guid.Parse("12345678-1234-1234-1234-123456789012"); // Configure settings client.Settings.DebugMessages = false; client.Settings.ConnectTimeoutSeconds = 10; // Wire up event handlers client.Events.ServerConnected += (sender, args) => { Console.WriteLine("Connected to server"); }; client.Events.ServerDisconnected += (sender, args) => { Console.WriteLine($"Disconnected from server: {args.Reason}"); }; client.Events.MessageReceived += (sender, args) => { Console.WriteLine($"Message from server: {Encoding.UTF8.GetString(args.Data)}"); }; // Connect to server await client.ConnectAsync(); Console.WriteLine($"Connected: {client.Connected}"); ``` -------------------------------- ### C# Watson TCP Client for Stream Data Handling Source: https://github.com/dotnet/watsontcp/blob/master/README.md Illustrates how to send and receive data as streams using Watson TCP. The client connects to a server, and includes event handlers for stream reception, demonstrating how to read data in chunks from a stream. The server-side setup for stream handling is also included. ```csharp // server WatsonTcpServer server = new WatsonTcpServer("127.0.0.1", 9000); server.Events.ClientConnected += ClientConnected; server.Events.ClientDisconnected += ClientDisconnected; server.Events.StreamReceived += StreamReceived; server.Start(); static void StreamReceived(object sender, StreamReceivedEventArgs args) { long bytesRemaining = args.ContentLength; int bytesRead = 0; byte[] buffer = new byte[65536]; using (MemoryStream ms = new MemoryStream()) { while (bytesRemaining > 0) { bytesRead = args.DataStream.Read(buffer, 0, buffer.Length); if (bytesRead > 0) { ms.Write(buffer, 0, bytesRead); bytesRemaining -= bytesRead; } } } Console.WriteLine( "Stream received from " + args.Client.ToString() + ": " + Encoding.UTF8.GetString(ms.ToArray())); } // client WatsonTcpClient client = new WatsonTcpClient("127.0.0.1", 9000); client.Events.ServerConnected += ServerConnected; client.Events.ServerDisconnected += ServerDisconnected; client.Events.StreamReceived += StreamReceived; client.Connect(); static void StreamReceived(object sender, StreamReceivedEventArgs args) { long bytesRemaining = args.ContentLength; int bytesRead = 0; byte[] buffer = new byte[65536]; using (MemoryStream ms = new MemoryStream()) { while (bytesRemaining > 0) { bytesRead = args.DataStream.Read(buffer, 0, buffer.Length); if (bytesRead > 0) { ms.Write(buffer, 0, bytesRead); bytesRemaining -= bytesRead; } } } Console.WriteLine("Stream received from server: " + Encoding.UTF8.GetString(ms.ToArray())); } ``` -------------------------------- ### Implement Preshared Key Authentication in Watson TCP .NET Source: https://context7.com/dotnet/watsontcp/llms.txt This example demonstrates how to set up and use preshared key authentication for secure communication with Watson TCP. It shows configuration on both the server and client sides, including handling authentication success and failure events. Ensure the WatsonTcp library is referenced. ```csharp using System; using System.Text; using System.Threading.Tasks; using WatsonTcp; // Server with preshared key WatsonTcpServer server = new WatsonTcpServer("127.0.0.1", 9000); server.Settings.PresharedKey = "MySuperSecretKey16BytesRequired!"; server.Events.AuthenticationSucceeded += (sender, args) => { Console.WriteLine($"Client {args.Client.Guid} authenticated successfully"); }; server.Events.AuthenticationFailed += (sender, args) => { Console.WriteLine($"Client authentication failed from {args.IpPort}"); }; server.Start(); // Client with preshared key WatsonTcpClient client = new WatsonTcpClient("127.0.0.1", 9000); client.Settings.PresharedKey = "MySuperSecretKey16BytesRequired!"; await client.ConnectAsync(); await client.AuthenticateAsync(); // Note: Keys must be exactly 16 bytes when used internally ``` -------------------------------- ### HTTP Framing Example Source: https://github.com/dotnet/watsontcp/blob/master/FRAMING.md Demonstrates the traditional HTTP header format, which uses string-based key-value pairs separated by newlines, ending with a double newline before the message body. This serves as a conceptual basis for WatsonTcp's framing. ```text Content-Type: text/plain[\r\n] Content-Length: 1234[\r\n] Authorization: hello@world.com[\r\n] ... other fields ...[\r\n] [\r\n] [data] ``` -------------------------------- ### C# Watson TCP Client with Custom GUID Specification Source: https://github.com/dotnet/watsontcp/blob/master/README.md Demonstrates how to assign a specific GUID to a Watson TCP client before establishing a connection. This is achieved by modifying the client's settings.Guid property. It also includes basic connection event handlers and stream reception. ```csharp WatsonTcpClient client = new WatsonTcpClient("127.0.0.1", 9000); client.Events.ServerConnected += ServerConnected; client.Events.ServerDisconnected += ServerDisconnected; client.Events.StreamReceived += StreamReceived; client.Settings.Guid = Guid.Parse("12345678-1234-1234-123456781234"); client.Connect(); ``` -------------------------------- ### C# Watson TCP Client with SSL Configuration Source: https://github.com/dotnet/watsontcp/blob/master/README.md Shows how to configure a Watson TCP client to use SSL for secure communication. This involves providing certificate file paths and optionally enabling settings for invalid certificates and mutual authentication. The server-side setup is also shown. ```csharp // server WatsonTcpServer server = new WatsonTcpServer("127.0.0.1", 9000, "test.pfx", "password"); server.Settings.AcceptInvalidCertificates = true; server.Settings.MutuallyAuthenticate = true; server.Start(); // client WatsonTcpClient client = new WatsonTcpClient("127.0.0.1", 9000, "test.pfx", "password"); client.Settings.AcceptInvalidCertificates = true; client.Settings.MutuallyAuthenticate = true; client.Connect(); ``` -------------------------------- ### Disconnect and Cleanup Watson TCP Clients and Servers in .NET Source: https://context7.com/dotnet/watsontcp/llms.txt This example demonstrates how to gracefully disconnect Watson TCP clients and servers, as well as how to dispose of their resources. It covers disconnecting a client, disconnecting a specific client from a server, and stopping the entire server. Ensure the WatsonTcp library is referenced. ```csharp using System; using System.Threading.Tasks; using WatsonTcp; // Client disconnect WatsonTcpClient client = new WatsonTcpClient("127.0.0.1", 9000); await client.ConnectAsync(); // Graceful disconnect client.Disconnect(); Console.WriteLine($"Connected: {client.Connected}"); // false // Or dispose (also disconnects) client.Dispose(); // Server disconnect specific client WatsonTcpServer server = new WatsonTcpServer("127.0.0.1", 9000); server.Start(); Guid clientGuid = Guid.Empty; server.Events.ClientConnected += (sender, args) => { clientGuid = args.Client.Guid; }; // Disconnect specific client server.DisconnectClient(clientGuid); // Check if client is connected bool isConnected = server.IsClientConnected(clientGuid); // Stop server (disconnects all clients) server.Stop(); // Dispose server server.Dispose(); ``` -------------------------------- ### Set Client GUID Before Connecting (C#) Source: https://github.com/dotnet/watsontcp/blob/master/CLAUDE.md Assigns a unique GUID to a WatsonTcp client before establishing a connection. This allows the server to identify and manage clients using their specific GUIDs. ```csharp client.Settings.Guid = myGuid; ``` -------------------------------- ### Send Message to Specific Client by GUID (C#) Source: https://github.com/dotnet/watsontcp/blob/master/CLAUDE.md Sends a message asynchronously to a specific client connected to the WatsonTcp server, identified by its unique GUID. This enables targeted communication within a multi-client environment. ```csharp server.SendAsync(clientGuid, data); ``` -------------------------------- ### WatsonTcp Framing Example Source: https://github.com/dotnet/watsontcp/blob/master/FRAMING.md Shows the WatsonTcp framing structure, where message metadata, including the 'len' (length prefix), is encapsulated in a JSON object. This JSON header is followed by a standard CRLF CRLF delimiter before the actual message data. ```json {"len":1234,"status":"Normal",...other fields...}[\r\n] [data] ``` -------------------------------- ### Send Messages (Fire-and-Forget) with WatsonTcp Source: https://context7.com/dotnet/watsontcp/llms.txt Send messages from client to server or server to clients without waiting for a response. Supports sending strings, byte arrays, and offset data. The server can send messages to specific clients by GUID or broadcast to all connected clients. ```csharp using System; using System.Collections.Generic; using System.Text; using System.Threading.Tasks; using WatsonTcp; // Client sending to server WatsonTcpClient client = new WatsonTcpClient("127.0.0.1", 9000); await client.ConnectAsync(); // Send string bool success = await client.SendAsync("Hello, server!"); if (!success) Console.WriteLine("Send failed"); // Send byte array byte[] data = Encoding.UTF8.GetBytes("Hello from bytes"); success = await client.SendAsync(data); // Send with offset (skip first N bytes) byte[] largeData = Encoding.UTF8.GetBytes("SKIP_THIS_PARTActual message"); success = await client.SendAsync(largeData, null, 14); // Skip first 14 bytes // Server sending to specific client WatsonTcpServer server = new WatsonTcpServer("127.0.0.1", 9000); server.Start(); // Get client GUID from connection event Guid clientGuid = Guid.Empty; server.Events.ClientConnected += (sender, args) => { clientGuid = args.Client.Guid; }; // Send to specific client by GUID success = await server.SendAsync(clientGuid, "Hello, client!"); if (!success) Console.WriteLine("Client not found or send failed"); // List all connected clients IEnumerable clients = server.ListClients(); foreach (var client in clients) { Console.WriteLine($"Client: {client.Guid} at {client.IpPort}"); await server.SendAsync(client.Guid, "Broadcast message"); } ``` -------------------------------- ### Basic C# Watson TCP Client Connection and Messaging Source: https://github.com/dotnet/watsontcp/blob/master/README.md Demonstrates how to establish a connection to a Watson TCP server, subscribe to connection and message events, send simple messages, send messages with metadata, and perform synchronous requests with timeouts. It requires the WatsonTcp library. ```csharp using WatsonTcp; static void Main(string[] args) { WatsonTcpClient client = new WatsonTcpClient("127.0.0.1", 9000); client.Events.ServerConnected += ServerConnected; client.Events.ServerDisconnected += ServerDisconnected; client.Events.MessageReceived += MessageReceived; client.Callbacks.SyncRequestReceivedAsync = SyncRequestReceived; client.Connect(); // check connectivity Console.WriteLine("Am I connected? " + client.Connected); // send a message client.Send("Hello!"); // send a message with metadata Dictionary md = new Dictionary(); md.Add("foo", "bar"); await client.SendAsync("Hello, client! Here's some metadata!", md); // send and wait for a response try { SyncResponse resp = await client.SendAndWaitAsync( 5000, "Hey, say hello back within 5 seconds!"); Console.WriteLine("My friend says: " + Encoding.UTF8.GetString(resp.Data)); } catch (TimeoutException) { Console.WriteLine("Too slow..."); } } static void MessageReceived(object sender, MessageReceivedEventArgs args) { Console.WriteLine("Message from server: " + Encoding.UTF8.GetString(args.Data)); } static void ServerConnected(object sender, ConnectionEventArgs args) { Console.WriteLine("Server connected"); } static void ServerDisconnected(object sender, DisconnectionEventArgs args) { Console.WriteLine("Server disconnected"); } static async Task SyncRequestReceived(SyncRequest req) { return new SyncResponse(req, "Hello back at you!"); } ``` -------------------------------- ### WatsonTcp Server Initialization with SSL (C#) Source: https://github.com/dotnet/watsontcp/blob/master/CLAUDE.md Initializes a WatsonTcp server with SSL/TLS support by providing the path to a PFX certificate file and its password. This enables secure communication. ```csharp new WatsonTcpServer(ip, port, pfxCertFile, pfxPassword); ``` -------------------------------- ### Running WatsonTcp under Mono (Command Line) Source: https://github.com/dotnet/watsontcp/blob/master/README.md Provides command-line instructions for running a WatsonTcp application under Mono, the open-source implementation of .NET. It recommends using the Ahead-of-Time (AOT) compiler and the --server flag for optimal performance. Note that TLS 1.2 is hardcoded and might need downgrading in some Mono environments. The specific flags are for AOT compilation and server mode. ```bash mono --aot=nrgctx-trampolines=8096,nimt-trampolines=8096,ntrampolines=4048 --server myapp.exe mono --server myapp.exe ``` -------------------------------- ### WatsonTcp Client Initialization with SSL (C#) Source: https://github.com/dotnet/watsontcp/blob/master/CLAUDE.md Initializes a WatsonTcp client with SSL/TLS support by providing the path to a PFX certificate file and its password. This enables secure communication. ```csharp new WatsonTcpClient(ip, port, pfxCertFile, pfxPassword); ``` -------------------------------- ### Build All Projects Including Tests (C#) Source: https://github.com/dotnet/watsontcp/blob/master/CLAUDE.md Builds all projects within the WatsonTcp repository, including the main library and all associated test projects. This ensures all components are compiled. ```bash dotnet build ``` -------------------------------- ### Build WatsonTcp Library (C#) Source: https://github.com/dotnet/watsontcp/blob/master/CLAUDE.md Builds the main WatsonTcp library using dotnet CLI. This command targets multiple .NET frameworks and automatically creates NuGet packages upon successful build. ```bash dotnet build src/WatsonTcp/WatsonTcp.csproj dotnet pack src/WatsonTcp/WatsonTcp.csproj ``` -------------------------------- ### Run Specific Test Server (C#) Source: https://github.com/dotnet/watsontcp/blob/master/CLAUDE.md Executes a specific test server project for WatsonTcp using the dotnet CLI. Allows targeting a particular .NET framework for testing server functionality. ```bash dotnet run --project src/Test.Server/Test.Server.csproj --framework net8.0 ``` -------------------------------- ### Run Specific Test Client (C#) Source: https://github.com/dotnet/watsontcp/blob/master/CLAUDE.md Executes a specific test client project for WatsonTcp using the dotnet CLI. Allows targeting a particular .NET framework for testing client functionality. ```bash dotnet run --project src/Test.Client/Test.Client.csproj --framework net8.0 dotnet run --project src/Test.Client/Test.Client.csproj --framework net462 ``` -------------------------------- ### C# WatsonTcp: List and Manage Connected Clients Source: https://context7.com/dotnet/watsontcp/llms.txt Demonstrates how to list all connected clients, check if a specific client is connected, and disconnect a client using WatsonTcp. It also shows how to track clients with custom metadata upon connection. ```csharp using System; using System.Collections.Generic; using System.Linq; using WatsonTcp; WatsonTcpServer server = new WatsonTcpServer("127.0.0.1", 9000); // Track clients with custom metadata server.Events.ClientConnected += (sender, args) => { // Set custom name for client ClientMetadata clientMeta = args.Client; clientMeta.Name = "WebClient-" + clientMeta.Guid.ToString().Substring(0, 8); // Attach custom metadata object clientMeta.Metadata = new { ConnectedAt = DateTime.UtcNow, UserAgent = "WatsonTcp Client v6.0" }; Console.WriteLine($"Client connected: {clientMeta.ToString()}"); }; server.Start(); // List all connected clients IEnumerable clients = server.ListClients(); Console.WriteLine($"Total clients: {clients.Count()}"); foreach (var client in clients) { Console.WriteLine($" GUID: {client.Guid}"); Console.WriteLine($" IP:Port: {client.IpPort}"); Console.WriteLine($" Name: {client.Name}"); Console.WriteLine($" Metadata: {client.Metadata}"); } // Check if specific client is connected Guid targetGuid = clients.First().Guid; bool connected = server.IsClientConnected(targetGuid); // Disconnect specific client if (connected) { server.DisconnectClient(targetGuid); } ``` -------------------------------- ### Send Message with Metadata (C#) Source: https://github.com/dotnet/watsontcp/blob/master/README.md Demonstrates how to send a message with associated metadata using WatsonTcp's SendAsync method. Metadata is passed as a Dictionary. Keys must be strings. For complex object values, deserialization is required on the receiving end. This method is suitable for small amounts of metadata (under 1KB) due to performance considerations. ```csharp using WatsonTcp; using System.Collections.Generic; using System.Text; using System.Threading.Tasks; // ... inside a method or class ... // Example of sending a message with metadata string clientGuid = "your-client-guid"; // Replace with actual client GUID Dictionary md = new Dictionary(); md.Add("foo", "bar"); await server.SendAsync(clientGuid, "Hello, client! Here's some metadata!", md); // Example of deserializing a received object (on the receiving end) // object myVal = args.Metadata["myKey"]; // MyClass instance = myVal.ToObject(); // Assuming ToObject extension method exists ``` -------------------------------- ### Configure Logging and Debugging in WatsonTCP (C#) Source: https://github.com/dotnet/watsontcp/blob/master/CLAUDE.md This snippet demonstrates how to enable debug messages, set a custom logger, and handle exceptions using the WatsonTCP client. It requires defining a custom logging method, like 'MyLoggerMethod', which accepts severity and message. ```csharp client.Settings.DebugMessages = true; client.Settings.Logger = MyLoggerMethod; client.Events.ExceptionEncountered += MyExceptionHandler; void MyLoggerMethod(Severity sev, string msg) { Console.WriteLine($"{sev}: {msg}"); } ``` -------------------------------- ### Bug Report: Sample Code for Widget Issue (.NET) Source: https://github.com/dotnet/watsontcp/blob/master/CONTRIBUTING.md This code snippet demonstrates a potential bug in the Widget class, specifically when attempting to shift it right. It's used within a bug report to reproduce the issue. ```csharp Widget widget = new Widget(); widget.ShiftRight(); ``` -------------------------------- ### Enable Logging and Exception Handling in Watson TCP .NET Source: https://context7.com/dotnet/watsontcp/llms.txt This snippet shows how to enable detailed debug messages and set up a custom logger for Watson TCP clients. It also demonstrates how to handle exceptions encountered during client operations. Ensure the WatsonTcp library is referenced. ```csharp using System; using WatsonTcp; WatsonTcpClient client = new WatsonTcpClient("127.0.0.1", 9000); // Enable debug messages (WARNING: very verbose) client.Settings.DebugMessages = true; // Set up logger client.Settings.Logger = (severity, message) => { string timestamp = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"); Console.WriteLine($"[{timestamp}] [{severity}] {message}"); // Severity levels: Debug, Info, Warn, Error, Alert if (severity == Severity.Error || severity == Severity.Alert) { // Log to file or external system } }; // Handle exceptions client.Events.ExceptionEncountered += (sender, args) => { Console.WriteLine($"Exception: {args.Json}"); Console.WriteLine($"Exception details: {args.Exception?.ToString()}"); }; await client.ConnectAsync(); ``` -------------------------------- ### Track Statistics for Watson TCP Clients and Servers in .NET Source: https://context7.com/dotnet/watsontcp/llms.txt This code snippet illustrates how to access and monitor connection statistics for both Watson TCP clients and servers. It shows how to view sent/received messages and bytes, uptime, and how to reset statistics. Ensure the WatsonTcp library is referenced. ```csharp using System; using WatsonTcp; WatsonTcpClient client = new WatsonTcpClient("127.0.0.1", 9000); await client.ConnectAsync(); // Send some messages await client.SendAsync("Message 1"); await client.SendAsync("Message 2"); // Access statistics Console.WriteLine($"Messages sent: {client.Statistics.SentMessages}"); Console.WriteLine($"Messages received: {client.Statistics.ReceivedMessages}"); Console.WriteLine($"Bytes sent: {client.Statistics.SentBytes}"); Console.WriteLine($"Bytes received: {client.Statistics.ReceivedBytes}"); Console.WriteLine($"Started at: {client.Statistics.StartTime}"); Console.WriteLine($"Uptime: {client.Statistics.UpTime}"); // Reset statistics (preserves StartTime and UpTime) client.Statistics.Reset(); // Server statistics work the same way WatsonTcpServer server = new WatsonTcpServer("127.0.0.1", 9000); server.Start(); Console.WriteLine($"Total connections: {server.Connections}"); Console.WriteLine($"Server messages sent: {server.Statistics.SentMessages}"); ``` -------------------------------- ### Length Prefixing Pseudocode for TCP Message Framing Source: https://github.com/dotnet/watsontcp/blob/master/FRAMING.md Illustrates the basic logic for receiving messages using a length prefix. It involves reading bytes to determine the message length, then reading the specified number of data bytes. This method is fundamental for TCP message framing. ```pseudocode Create an empty byte array buffer Loop Read one byte b from the socket If b != : append to buffer While character read is not : Convert buffer contents to an integer len Read len bytes from the network as data ``` -------------------------------- ### Send Messages with Metadata using WatsonTcp Source: https://context7.com/dotnet/watsontcp/llms.txt Include metadata dictionaries with messages for additional context when sending data. The server can access and process this metadata upon receiving messages. Metadata should be kept small (under 1KB) due to CPU-intensive parsing. ```csharp using System; using System.Collections.Generic; using System.Text; using System.Threading.Tasks; using WatsonTcp; WatsonTcpClient client = new WatsonTcpClient("127.0.0.1", 9000); await client.ConnectAsync(); // Create metadata dictionary Dictionary metadata = new Dictionary { { "username", "alice" }, { "timestamp", DateTime.UtcNow }, { "messageType", "chat" }, { "priority", 5 } }; // Send with metadata await client.SendAsync("Hello with metadata!", metadata); // Server receiving and accessing metadata WatsonTcpServer server = new WatsonTcpServer("127.0.0.1", 9000); server.Events.MessageReceived += (sender, args) => { if (args.Metadata != null && args.Metadata.ContainsKey("username")) { string username = args.Metadata["username"].ToString(); Console.WriteLine($"Message from user: {username}"); } // Access simple types directly if (args.Metadata.ContainsKey("priority")) { int priority = Convert.ToInt32(args.Metadata["priority"]); Console.WriteLine($"Priority: {priority}"); } Console.WriteLine($"Message: {Encoding.UTF8.GetString(args.Data)}"); }; server.Start(); // WARNING: Keep metadata small (<1KB) to avoid CPU overhead // Metadata parsing is CPU-intensive and evaluated byte-by-byte ``` -------------------------------- ### Enable Logging and Debugging in WatsonTcp (C#) Source: https://github.com/dotnet/watsontcp/blob/master/README.md Enables debug messages and sets a custom logger for troubleshooting WatsonTcp connections. The logger captures messages with severity levels and prints them to the console. This is the first step in diagnosing connection issues. ```csharp client.Settings.DebugMessages = true; client.Settings.Logger = MyLoggerMethod; private void MyLoggerMethod(Severity sev, string msg) { Console.WriteLine(sev.ToString() + ": " + msg); } ``` -------------------------------- ### Synchronous Request/Response Pattern with WatsonTcp Source: https://context7.com/dotnet/watsontcp/llms.txt Implement a synchronous request/response pattern where a client sends a message and waits for a response from the server. This pattern includes timeout handling for requests. The server can also send responses with metadata. ```csharp using System; using System.Text; using System.Threading.Tasks; using WatsonTcp; // Client requesting from server WatsonTcpClient client = new WatsonTcpClient("127.0.0.1", 9000); // Set up sync request handler (receives requests, returns responses) client.Callbacks.SyncRequestReceivedAsync = async (SyncRequest req) => { Console.WriteLine($"Sync request: {Encoding.UTF8.GetString(req.Data)}"); return new SyncResponse(req, "Client response data"); }; await client.ConnectAsync(); // Send request and wait for response (5 second timeout) try { SyncResponse response = await client.SendAndWaitAsync( 5000, "What is your status?" ); Console.WriteLine($"Server replied: {Encoding.UTF8.GetString(response.Data)}"); Console.WriteLine($"Conversation ID: {response.ConversationGuid}"); } catch (TimeoutException) { Console.WriteLine("Request timed out after 5 seconds"); } catch (Exception ex) { Console.WriteLine($"Request failed: {ex.Message}"); } // Server handling sync requests WatsonTcpServer server = new WatsonTcpServer("127.0.0.1", 9000); server.Callbacks.SyncRequestReceivedAsync = async (SyncRequest req) => { string question = Encoding.UTF8.GetString(req.Data); Console.WriteLine($"Client {req.Client.Guid} asks: {question}"); // Create response with metadata Dictionary responseMeta = new Dictionary { { "serverTime", DateTime.UtcNow }, { "status", "healthy" } }; return new SyncResponse(req, responseMeta, "All systems operational"); }; server.Start(); ``` -------------------------------- ### Handle Large Data with Stream-Based Messaging in C# Source: https://context7.com/dotnet/watsontcp/llms.txt Efficiently receive and send large messages as streams using Watson TCP. Configure the MaxProxiedStreamSize to differentiate between in-memory buffering for smaller messages and raw stream handling for larger ones. This avoids blocking the main thread for large data transfers. ```csharp using System; using System.IO; using System.Text; using System.Threading.Tasks; using WatsonTcp; // Server receiving streams WatsonTcpServer server = new WatsonTcpServer("127.0.0.1", 9000); // Set MaxProxiedStreamSize threshold (default 64MB) // Messages smaller than this are buffered in MemoryStream (async) // Messages larger than this use the raw stream (sync, blocks until read) server.Settings.MaxProxiedStreamSize = 10 * 1024 * 1024; // 10 MB server.Events.StreamReceived += (sender, args) => { Console.WriteLine($"Stream from {args.Client.Guid}, Length: {args.ContentLength} bytes"); long bytesRemaining = args.ContentLength; int bytesRead = 0; byte[] buffer = new byte[65536]; using (MemoryStream ms = new MemoryStream()) { while (bytesRemaining > 0) { bytesRead = args.DataStream.Read(buffer, 0, buffer.Length); if (bytesRead > 0) { ms.Write(buffer, 0, bytesRead); bytesRemaining -= bytesRead; } } Console.WriteLine($"Received: {Encoding.UTF8.GetString(ms.ToArray())}"); } }; server.Start(); // Client sending stream WatsonTcpClient client = new WatsonTcpClient("127.0.0.1", 9000); await client.ConnectAsync(); byte[] data = Encoding.UTF8.GetBytes("Large message content"); using (MemoryStream ms = new MemoryStream(data)) { Dictionary metadata = new Dictionary { { "filename", "data.txt" }, { "contentType", "text/plain" } }; bool success = await client.SendAsync(data.Length, ms, metadata); Console.WriteLine($"Stream sent: {success}"); } // IMPORTANT: Only set ONE of Events.MessageReceived or Events.StreamReceived // If both are set, MessageReceived takes precedence ``` -------------------------------- ### Send Async Message with Metadata (C#) Source: https://github.com/dotnet/watsontcp/blob/master/CLAUDE.md Sends an asynchronous message with associated metadata using WatsonTcp. This method is preferred for non-blocking operations and supports sending custom metadata with the message payload. ```csharp SendAsync(data, metadata); ``` -------------------------------- ### Send and Wait for Response (C#) Source: https://github.com/dotnet/watsontcp/blob/master/CLAUDE.md Sends an asynchronous message and waits for a synchronous response within a specified timeout using WatsonTcp. Returns a SyncResponse object containing the response data. ```csharp SendAndWaitAsync(timeout, data); ``` -------------------------------- ### Configure TCP Keepalives for WatsonTcp Server (C#) Source: https://github.com/dotnet/watsontcp/blob/master/README.md Enables and configures TCP keepalive settings for the WatsonTcp server. This is primarily used to detect and handle network interface issues or disconnections. Note that keepalives are only supported in .NET Core and .NET Framework, not .NET Standard. ```csharp server.Keepalive.EnableTcpKeepAlives = true; server.Keepalive.TcpKeepAliveInterval = 5; // seconds to wait before sending subsequent keepalive server.Keepalive.TcpKeepAliveTime = 5; // seconds to wait before sending a keepalive server.Keepalive.TcpKeepAliveRetryCount = 5; // number of failed keepalive probes before terminating connection ``` -------------------------------- ### Implement Exception Handling for WatsonTcp (C#) Source: https://github.com/dotnet/watsontcp/blob/master/README.md Subscribes to the ExceptionEncountered event to handle exceptions that occur within WatsonTcp. When an exception is caught, it logs the JSON payload associated with the exception to the console. ```csharp client.Events.ExceptionEncountered += MyExceptionEvent; private void MyExceptionEvent(object sender, ExceptionEventArgs args) { Console.WriteLine(args.Json); } ``` -------------------------------- ### Configure TCP Keepalives for Connection Monitoring in C# Source: https://context7.com/dotnet/watsontcp/llms.txt Implement TCP keepalives on both the server and client to proactively monitor connection health. This feature helps detect network failures or dead connections by sending periodic probes. Settings include the initial delay, interval between probes, and the number of retries before considering the connection lost. ```csharp using System; using WatsonTcp; // Server with keepalives WatsonTcpServer server = new WatsonTcpServer("127.0.0.1", 9000); // Enable TCP keepalives (not supported in .NET Standard) server.Keepalive.EnableTcpKeepAlives = true; server.Keepalive.TcpKeepAliveTime = 5; // Wait 5 seconds before first probe server.Keepalive.TcpKeepAliveInterval = 5; // Wait 5 seconds between probes server.Keepalive.TcpKeepAliveRetryCount = 3; // Fail after 3 missed probes (.NET Core only) // Note: .NET Framework always uses 10 retries regardless of TcpKeepAliveRetryCount server.Events.ClientDisconnected += (sender, args) => { Console.WriteLine($"Client disconnected: {args.Reason}"); // Possible reasons: Normal, Timeout, Kicked, Removed, Shutdown }; server.Start(); // Client with keepalives WatsonTcpClient client = new WatsonTcpClient("127.0.0.1", 9000); client.Keepalive.EnableTcpKeepAlives = true; client.Keepalive.TcpKeepAliveTime = 5; client.Keepalive.TcpKeepAliveInterval = 5; client.Keepalive.TcpKeepAliveRetryCount = 3; await client.ConnectAsync(); ``` -------------------------------- ### Set Idle Timeout for Clients and Servers in C# Source: https://context7.com/dotnet/watsontcp/llms.txt Configure automatic disconnection of idle clients or servers after a specified period of inactivity. The server can disconnect idle clients, and the client can disconnect from an idle server. Timeouts are reset upon receiving data and are evaluated at configurable intervals. ```csharp using System; using WatsonTcp; // Server: disconnect idle clients after 30 seconds WatsonTcpServer server = new WatsonTcpServer("127.0.0.1", 9000); server.Settings.IdleClientTimeoutSeconds = 30; // Timeout is reset when a message is received from the client // Clients are evaluated every 5 seconds (not precise timing) server.Events.ClientDisconnected += (sender, args) => { if (args.Reason == DisconnectReason.Timeout) { Console.WriteLine($"Client {args.Client.Guid} timed out due to inactivity"); } }; server.Start(); // Client: disconnect from idle server after 30 seconds WatsonTcpClient client = new WatsonTcpClient("127.0.0.1", 9000); client.Settings.IdleServerTimeoutMs = 30000; client.Settings.IdleServerEvaluationIntervalMs = 5000; // Check every 5 seconds client.Events.ServerDisconnected += (sender, args) => { if (args.Reason == DisconnectReason.Timeout) { Console.WriteLine("Disconnected: server was idle for too long"); } }; await client.ConnectAsync(); ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.