### Install and Start TCP Service Source: https://github.com/rrqm/touchsocket/blob/master/handbook/blog/CreateHighlyAvailableTcpService.mdx Use these commands to create, configure, and start the HighlyAvailableTcpService as a Windows service. ```bash cd .. sc create HighlyAvailableTcpService binPath= %~dp0DocsWorkerService.exe start= auto sc description HighlyAvailableTcpService "HighlyAvailableTcpService" Net Start HighlyAvailableTcpService pause ``` -------------------------------- ### Setup and Start HTTP JSON-RPC Server Source: https://context7.com/rrqm/touchsocket/llms.txt Configures and starts an HTTP server for JSON-RPC. Use the `UseHttpJsonRpc` plugin for HTTP-based JSON-RPC communication. ```csharp var httpService = new HttpService(); await httpService.SetupAsync(new TouchSocketConfig() .SetListenIPHosts(9902) .ConfigurePlugins(a => { a.UseHttpJsonRpc() .ConfigureRpcStore(store => store.RegisterServer()); })); await httpService.StartAsync(); ``` -------------------------------- ### Setup and Start TCP JSON-RPC Server Source: https://context7.com/rrqm/touchsocket/llms.txt Configures and starts a TCP server that handles JSON-RPC requests. The `UseJsonRpc` plugin is essential for JSON-RPC functionality. ```csharp var tcpJsonRpcService = new TcpService(); await tcpJsonRpcService.SetupAsync(new TouchSocketConfig() .SetListenIPHosts(9901) .ConfigurePlugins(a => { a.UseJsonRpc() .ConfigureRpcStore(store => store.RegisterServer()); })); await tcpJsonRpcService.StartAsync(); ``` -------------------------------- ### Start Local Development Server Source: https://github.com/rrqm/touchsocket/blob/master/handbook/README.md Starts a local development server. Changes are reflected live without restarting. ```bash $ yarn start ``` -------------------------------- ### Install TouchSocket.WebApi NuGet Package Source: https://github.com/rrqm/touchsocket/blob/master/handbook/docs/webapi.mdx Use this command to install the necessary NuGet package for TouchSocket.WebApi. ```bash Install-Package TouchSocket.WebApi ``` -------------------------------- ### Install RPC Rate Limiting Package Source: https://github.com/rrqm/touchsocket/blob/master/handbook/docs/rpcratelimiting.mdx Install the TouchSocket.Rpc.RateLimiting package using the NuGet Package Manager. ```bash Install-Package TouchSocket.Rpc.RateLimiting ``` -------------------------------- ### Setup and Start WebSocket JSON-RPC Server Source: https://context7.com/rrqm/touchsocket/llms.txt Configures and starts an HTTP server that also handles JSON-RPC requests over WebSockets. Use the `UseWebSocketJsonRpc` plugin for this transport. ```csharp var wsService = new HttpService(); await wsService.SetupAsync(new TouchSocketConfig() .SetListenIPHosts(9903) .ConfigurePlugins(a => { a.UseWebSocketJsonRpc() .ConfigureRpcStore(store => store.RegisterServer()); })); await wsService.StartAsync(); ``` -------------------------------- ### Plugin Execution Analysis Example Source: https://github.com/rrqm/touchsocket/blob/master/handbook/docs/pluginsmanager.mdx Demonstrates the execution flow and callback mechanism of plugins with different input scenarios. ```text 请输入hello,或者hi test SayHelloPlugin------Enter SayHiPlugin------Enter LastSayPlugin------Enter 您输入的test似乎不被任何插件处理 LastSayPlugin------Leave SayHiPlugin------Leave SayHelloPlugin------Leave 请输入hello,或者hi hello SayHelloPlugin------Enter SayHelloPlugin------Say 请输入hello,或者hi hi SayHelloPlugin------Enter SayHiPlugin------Enter SayHiPlugin------Say SayHelloPlugin------Leave 请输入hello,或者hi ``` -------------------------------- ### Web API Authentication and Authorization Example Source: https://github.com/rrqm/touchsocket/blob/master/handbook/docs/webapi-auth.mdx This C# example shows how to set up an HttpService with authentication plugins, define secure API endpoints using attributes like [Authorize] and [RoleAuthorize], and how a client can make authenticated requests. ```csharp // 服务器端 var service = new HttpService(); await service.SetupAsync(new TouchSocketConfig() .SetListenIPHosts(7789) .ConfigurePlugins(a => { a.Add(); // 全局鉴权 a.UseWebApi(); a.UseDefaultHttpServicePlugin(); })); await service.StartAsync(); // API 服务 public partial class SecureApiServer : SingletonRpcServer { [WebApi(Method = HttpMethodType.Get)] public string PublicInfo() { return "This is public information"; } [Authorize] [WebApi(Method = HttpMethodType.Get)] public string UserInfo(IWebApiCallContext context) { var token = context.HttpContext.Request.Headers["Authorization"]; return $"User info (token: {token})"; } [RoleAuthorize("Admin")] [WebApi(Method = HttpMethodType.Post)] public string AdminAction() { return "Admin action executed"; } } // 客户端调用 var client = new HttpClient(); client.DefaultRequestHeaders.Add("Authorization", "Bearer valid-token"); var result = await client.GetStringAsync("http://localhost:7789/secureapiserver/userinfo"); Console.WriteLine(result); ``` -------------------------------- ### Create WebSocket Server Source: https://github.com/rrqm/touchsocket/blob/master/handbook/docs/websocketservice.mdx Use the WebSocket plugin to directly specify URL routes for receiving WebSocket connections. This is the simplest way to get started. ```csharp builder.Services.AddWebSocket(); builder.Services.AddSingleton(); builder.Services.AddSingleton(); builder.Services.AddSingleton(); builder.Services.AddSingleton(); builder.Services.AddSingleton(); public class MyWebSocketService : WebSocketService { public MyWebSocketService(IHttpContextAccessor httpContextAccessor) : base(httpContextAccessor) { } protected override void OnConnected() { Console.WriteLine("WebSocket connected!"); base.OnConnected(); } protected override void OnReceived(ReceivedDataEventArgs e) { Console.WriteLine($"Received data: {e.Data}"); base.OnReceived(e); } protected override void OnClosed() { Console.WriteLine("WebSocket closed!"); base.OnClosed(); } } ``` -------------------------------- ### Http服务器执行响应 Source: https://github.com/rrqm/touchsocket/blob/master/handbook/docs/httpservice.mdx Send the constructed response. This example responds with 'hello' text. ```csharp await e.Context.Response.AnswerAsync(); ``` -------------------------------- ### Configure and Start WebAPI Server Source: https://github.com/rrqm/touchsocket/blob/master/handbook/docs/webapi.mdx Configure the server with listening ports, logging, RPC storage, register services, and enable the WebAPI plugin. Use UseDefaultHttpServicePlugin for handling common HTTP scenarios like 404s. ```csharp var client = new TouchSocket.Core.TouchSocketBasicConfig() .SetListenIPHosts(7789) .AddConsoleLogger() .AddRpcStore() .RegisterServer() .UseWebApi() .UseDefaultHttpServicePlugin(); client.Connect(); Console.ReadKey(); ``` -------------------------------- ### Install Project Dependencies Source: https://github.com/rrqm/touchsocket/blob/master/handbook/README.md Installs project dependencies using Yarn. ```bash $ yarn ``` -------------------------------- ### Start a TcpService Source: https://github.com/rrqm/touchsocket/blob/master/README.md Configure and start a TCP service to listen for incoming connections on a specified port. Event handlers for connection, disconnection, and message reception can be set. ```csharp TcpService service = new TcpService(); service.Connected = (client, e) => EasyTask.CompletedTask; service.Closed = (client, e) => EasyTask.CompletedTask; service.Received = (client, e) => { string str = e.Memory.Span.ToString(Encoding.UTF8); Console.WriteLine($"Received: {str}"); return EasyTask.CompletedTask; }; await service.StartAsync(7789); ``` -------------------------------- ### UdpSession UDP Server and Client Setup Source: https://context7.com/rrqm/touchsocket/llms.txt Demonstrates setting up a UDP server to receive and reply to messages, and a UDP client to send messages. Ensure the server is configured with a bind IP and port, and the client with a remote host and port. ```csharp using TouchSocket.Sockets; // ---- UDP Server ---- var udpServer = new UdpSession(); udpServer.Received = async (session, e) => { string msg = Encoding.UTF8.GetString(e.Memory.Span); Console.WriteLine($"UDP Received from {e.EndPoint}: {msg}"); // Reply to sender await session.SendAsync(e.EndPoint, Encoding.UTF8.GetBytes($"Pong: {msg}")); }; await udpServer.SetupAsync(new TouchSocketConfig() .SetBindIPHost(new IPHost(9090)) .SetUdpDataHandlingAdapter(() => new NormalUdpDataHandlingAdapter())); await udpServer.StartAsync(); // ---- UDP Client ---- var udpClient = new UdpSession(); await udpClient.SetupAsync(new TouchSocketConfig() .SetBindIPHost(new IPHost(0)) // bind to random free port .SetRemoteIPHost("127.0.0.1:9090")); await udpClient.StartAsync(); await udpClient.SendAsync(Encoding.UTF8.GetBytes("Hello UDP")); ``` -------------------------------- ### Install TouchSocket Packages Source: https://context7.com/rrqm/touchsocket/llms.txt Install the necessary TouchSocket NuGet packages for different functionalities like core TCP/UDP, HTTP/WebSocket, RPC protocols, and hosting integration. ```xml ``` -------------------------------- ### Activate TouchSocketPro with License Key Source: https://github.com/rrqm/touchsocket/blob/master/handbook/docs/enterprise.mdx Initialize TouchSocketPro by setting the LicenceKey during application startup. Ensure all TouchSocket projects are uninstalled and TouchSocketPro is installed. ```csharp Enterprise.LicenceKey = "密钥"; ``` -------------------------------- ### Http服务器使用插件 Source: https://github.com/rrqm/touchsocket/blob/master/handbook/docs/httpservice.mdx Example of using a plugin for response handling in HttpService. ```csharp await e.Context.Response.UsePlugin().AnswerAsync(); ``` -------------------------------- ### Implement Server Started Plugin for Dynamic Listening Source: https://github.com/rrqm/touchsocket/blob/master/handbook/blog/CreateHighlyAvailableTcpService.mdx Implement the IServerStartedPlugin to dynamically add TCP listeners when the server starts. This allows for flexible configuration of listening endpoints based on options. ```csharp internal class TcpListenPlugin : PluginBase, IServerStartedPlugin { private readonly ILogger m_logger; public TcpListenPlugin(IOptions ioption, ILogger logger) { this.Options = ioption.Value.Options ?? []; this.m_logger = logger; } [NotNull] public HighlyAvailableTcpServiceOption[]? Options { get; } public async Task OnServerStarted(IServiceBase sender, ServiceStateEventArgs e) { if (e.ServerState == ServerState.Running && sender is ITcpServiceBase tcpServiceBase) { var count = 0; foreach (var item in this.Options) { try { var listenOption = new TcpListenOption() { IpHost = new IPHost($"{item.Ip}:{item.Port}"), Backlog = item.Backlog, Name = item.Name, ServiceSslOption = GetServiceSslOption(item.SslPath,item.SslKey) }; tcpServiceBase.AddListen(listenOption); count++; this.m_logger.LogInformation("监听成功,Name={Name},IpHost={Ip}:{Port}", item.Name, item.Ip, item.Port); } catch (Exception ex) { this.m_logger.LogError(ex, "添加监听失败"); } } this.m_logger.LogInformation("共添加{Count}个监听", count); } await e.InvokeNext(); } private static ServiceSslOption? GetServiceSslOption(string? sslPath, string? sslKey) { if (string.IsNullOrEmpty(sslPath) || string.IsNullOrEmpty(sslKey)) { return null; } return new ServiceSslOption() { Certificate=new X509Certificate2(sslPath,sslKey) }; } } ``` -------------------------------- ### Unified Client/Server API Example Source: https://github.com/rrqm/touchsocket/blob/master/README.md TouchSocket provides a consistent set of APIs for various protocols like TCP, UDP, and WebSocket, ensuring a low learning curve. Examples include connecting, sending data, and handling received events. ```csharp client.ConnectAsync(...) client.SendAsync(...) client.Received += ... ``` -------------------------------- ### Start Tcp DmtpRpc Server Source: https://github.com/rrqm/touchsocket/blob/master/handbook/docs/dmtprpc.mdx Initialize and start a Dmtp server using the Tcp protocol, registering the previously defined RPC services. This involves configuring the server with appropriate plugins and services. ```csharp var dmtp = Dmtp.CreateDmtpServer(new TouchSocketConfig()) .RegisterDmtpRpc("MyRpcServer") // Register the RPC service .Build(); dmtp.Start(); ``` -------------------------------- ### DmtpRpc Client Setup and Connection Source: https://context7.com/rrqm/touchsocket/llms.txt Initializes and connects a DmtpRpc client to a server. Ensure the DmtpRpc plugin is configured for the client and the remote host is correctly specified. ```csharp // ---- 3. Create client ---- var client = new TcpDmtpClient(); await client.SetupAsync(new TouchSocketConfig() .SetRemoteIPHost("127.0.0.1:8848") .ConfigurePlugins(a => a.UseDmtpRpc())); await client.ConnectAsync(); ``` -------------------------------- ### Mixed Parameter Sources Example Source: https://github.com/rrqm/touchsocket/blob/master/handbook/docs/webapi-parameter.mdx Demonstrates how to combine parameters from different sources (query, header, body) in a single API endpoint. Each parameter can be explicitly bound using its respective attribute. ```csharp public class MyClass { public int A { get; set; } public int B { get; set; } } [WebApi(Method = HttpMethodType.Post)] public string MixedParams( [FromQuery] int id, [FromHeader] string authorization, [FromBody] MyClass data) { return $"ID: {id}, Data: {data.A + data.B}"; } ``` -------------------------------- ### Create TCP Client with TerminatorPackageAdapter Source: https://github.com/rrqm/touchsocket/blob/master/handbook/docs/packageadapter.mdx Initializes a TCP client using TerminatorPackageAdapter, defining '\r\n' as the package terminator. Includes standard client setup for remote host and logging. ```csharp private static async Task CreateClient() { var client = new TcpClient(); //载入配置 await client.SetupAsync(new TouchSocketConfig() .SetRemoteIPHost("127.0.0.1:7789") .SetTcpDataHandlingAdapter(() => new TerminatorPackageAdapter("\r\n")) .ConfigureContainer(a => { a.AddConsoleLogger();//添加一个日志注入 })); await client.ConnectAsync();//调用连接,当连接不成功时,会抛出异常。 client.Logger.Info("客户端成功连接"); return client; } ``` -------------------------------- ### DmtpRpc TCP Server Setup Source: https://context7.com/rrqm/touchsocket/llms.txt Sets up a TCP DmtpService, configuring it to listen on a specified port and enabling the DmtpRpc plugin. Register your service class with the RpcStore. ```csharp // ---- 2. Start TCP DMTP server ---- var server = new TcpDmtpService(); await server.SetupAsync(new TouchSocketConfig() .SetListenIPHosts(8848) .ConfigurePlugins(a => { a.UseDmtpRpc() .ConfigureRpcStore(store => { store.RegisterServer(); }); }) .ConfigureContainer(a => a.AddConsoleLogger())); await server.StartAsync(); ``` -------------------------------- ### Create TCP Client with FixedSizePackageAdapter Source: https://github.com/rrqm/touchsocket/blob/master/handbook/docs/packageadapter.mdx Configures a TCP client to use the FixedSizePackageAdapter, specifying a fixed package size of 10 bytes. Includes basic setup for remote host, logging, and connection. ```csharp private static async Task CreateClient() { var client = new TcpClient(); //载入配置 await client.SetupAsync(new TouchSocketConfig() .SetRemoteIPHost("127.0.0.1:7789") .SetTcpDataHandlingAdapter(() => new FixedSizePackageAdapter(10)) .ConfigureContainer(a => { a.AddConsoleLogger();//添加一个日志注入 })); await client.ConnectAsync();//调用连接,当连接不成功时,会抛出异常。 client.Logger.Info("客户端成功连接"); return client; } ``` -------------------------------- ### Implement and Register Plugins Source: https://context7.com/rrqm/touchsocket/llms.txt Shows how to implement plugins, register them with the PluginManager, and use delegate shortcuts. Plugins can be configured as singletons. ```csharp [PluginOption(Singleton = true)] public class HelloPlugin : PluginBase, ISayPlugin { public async Task OnSay(object sender, SayEventArgs e) { if (e.Words == "hello") { Console.WriteLine("HelloPlugin handled"); e.Handled = true; // stop chain return; } await e.InvokeNext(); // pass to next plugin } } public class FallbackPlugin : PluginBase, ISayPlugin { public async Task OnSay(object sender, SayEventArgs e) { Console.WriteLine($"FallbackPlugin: no one handled '{e.Words}'"); await e.InvokeNext(); } } // ---- Wire up and trigger ---- var container = new Container(); var pluginManager = new PluginManager(container) { Enable = true }; pluginManager.Add(); pluginManager.Add(); // Delegate shortcut (no class needed) pluginManager.Add(typeof(ISayPlugin), async (object sender, SayEventArgs e) => { Console.WriteLine($"Delegate intercepted: {e.Words}"); await e.InvokeNext(); }); await pluginManager.RaiseAsync(typeof(ISayPlugin), this, new SayEventArgs { Words = "hello" }); // Output: HelloPlugin handled await pluginManager.RaiseAsync(typeof(ISayPlugin), this, new SayEventArgs { Words = "world" }); // Output: Delegate intercepted: world // FallbackPlugin: no one handled 'world' ``` -------------------------------- ### Create a Simple TCP Server with Delegate Callbacks Source: https://context7.com/rrqm/touchsocket/llms.txt Set up a basic TCP server using delegate callbacks for connection, disconnection, and data reception. This approach is suitable for simple use cases, but the plugin system is recommended for production. ```csharp using TouchSocket.Core; using TouchSocket.Sockets; using System.Text; // ---- Simple delegate-based server ---- var service = new TcpService(); service.Connecting = (client, e) => { Console.WriteLine($"Client connecting: {client.IP}:{client.Port}"); return EasyTask.CompletedTask; }; service.Connected = (client, e) => { Console.WriteLine($"Client connected, Id={client.Id}"); return EasyTask.CompletedTask; }; service.Closed = (client, e) => { Console.WriteLine($"Client disconnected, Id={client.Id}, Reason={e.Message}"); return EasyTask.CompletedTask; }; service.Received = async (client, e) => { string text = Encoding.UTF8.GetString(e.Memory.Span); Console.WriteLine($"[{client.Id}] Received: {text}"); // Echo back await client.SendAsync(Encoding.UTF8.GetBytes($"Echo: {text}")); }; await service.SetupAsync(new TouchSocketConfig() .SetListenIPHosts(7789) // listen on 0.0.0.0:7789 .SetMaxCount(10000) // max simultaneous connections .ConfigureContainer(a => { a.AddConsoleLogger(); }) .ConfigurePlugins(a => { a.UseReconnection(); // reconnect plugin (for clients) })); await service.StartAsync(); Console.WriteLine("Server started. Press any key to stop."); Console.ReadKey(); ``` -------------------------------- ### 简单创建HttpClient Source: https://github.com/rrqm/touchsocket/blob/master/handbook/docs/httpclient.mdx 直接使用SetupAsync和ConnectAsync方法创建并连接HttpClient。 ```csharp var client = new HttpClient(); await client.ConnectAsync("http://127.0.0.1:7219"); ``` -------------------------------- ### 创建Mqtt服务器 Source: https://github.com/rrqm/touchsocket/blob/master/handbook/docs/mqttservice.mdx Directly create MqttTcpService and configure the basic listening address and plugins. ```csharp var service = TouchSocketConfig.CreateWithMqtt().Build(); service.AddMqttPlugin(new MyMqttConnectingPlugin()); service.AddMqttPlugin(new MyMqttConnectedPlugin()); service.AddMqttPlugin(new MyMqttClosingPlugin()); service.AddMqttPlugin(new MyMqttClosedPlugin()); service.AddMqttPlugin(new MyMqttReceivingPlugin()); service.AddMqttPlugin(new MyMqttReceivedPlugin()); service.Setup( new TouchSocketConfig() .SetListenIPHost(new IPHost("127.0.0.1:1883")) ).FireAndForget(); ``` -------------------------------- ### GET Request with WebApiClient Source: https://github.com/rrqm/touchsocket/blob/master/handbook/docs/webapi-client.mdx Shows how to perform a GET request using the WebApiClient, including query parameters and strong typing. ```APIDOC ## GET Request with WebApiClient ### Description Executes a GET request to a specified endpoint using `WebApiRequest` and retrieves a strongly-typed result. ### Method GET ### Endpoint `/apiserver/sum` (relative to configured host) ### Parameters #### Query Parameters - **a** (int) - Required - The first number. - **b** (int) - Required - The second number. ### Usage ```csharp var request = new WebApiRequest("/apiserver/sum") .AddQuery("a", 10) .AddQuery("b", 20); var result = await client.InvokeTAsync(request); ``` ### Response #### Success Response (200) - **T** (int) - The strongly-typed result of the request. ``` -------------------------------- ### Using Plugins Source: https://github.com/rrqm/touchsocket/blob/master/handbook/docs/webapi-client.mdx Demonstrates how to register and use plugins with the WebApiClient. ```APIDOC ## Using Plugins ### Description Configures the `WebApiClient` to utilize custom plugins for request and response processing. ### Usage ```csharp var client = new WebApiClient() .SetRemoteIPHost("localhost:7789") .ConfigurePlugins(plugins => { plugins.Add(); // Add request plugin plugins.Add(); // Add response plugin }); ``` ### Common Scenarios - **Authentication**: Add authentication tokens in request plugins. - **Logging**: Implement logging within request and response plugins. - **Retry Logic**: Implement retry mechanisms in response plugins based on status codes. ``` -------------------------------- ### Create WebApiClientSlim Source: https://github.com/rrqm/touchsocket/blob/master/handbook/docs/webapi-client.mdx Shows how to instantiate the lightweight WebApiClientSlim, which wraps System.Net.Http.HttpClient. ```APIDOC ## Create WebApiClientSlim ### Description Initializes a `WebApiClientSlim` instance, providing a lightweight wrapper around `System.Net.Http.HttpClient`. ### Method Instantiation ### Usage ```csharp // Using IHttpClientFactory (recommended for .NET 6.0+) var httpClientFactory = serviceProvider.GetRequiredService(); var client = new WebApiClientSlim(httpClientFactory.CreateClient()); // Or directly with an HttpClient instance var httpClient = new HttpClient(); var client = new WebApiClientSlim(httpClient); ``` ### Notes - Compatible with .NET 6.0+ and .NET 4.8.1. - Leverages `IHttpClientFactory` for connection pooling and management. ``` -------------------------------- ### Default GET Request Parameter Binding Source: https://github.com/rrqm/touchsocket/blob/master/handbook/docs/webapi-parameter.mdx For GET requests, all parameters are automatically bound from the query string by default. No explicit attributes are needed for simple types. ```csharp [WebApi(Method = HttpMethodType.Get)] public string Sum(int a, int b) { return $"a={a}, b={b}"; } ``` -------------------------------- ### Generated Extension Method Example Source: https://github.com/rrqm/touchsocket/blob/master/handbook/docs/rpcgenerateproxy.mdx Example of a generated extension method for an RPC client. This method is automatically created based on the interface definition and the GeneratorRpcProxy attribute. ```csharp public static LoginResponse Login(this TClient client,LoginRequest request,IInvokeOption invokeOption = default) where TClient:IRpcClient { if (client.TryCanInvoke?.Invoke(client)==false) { throw new RpcException("Rpc无法执行。"); } object[] parameters = new object[]{request}; RpcClassLibrary.Models.LoginResponse returnData=client.Invoke("rpcclasslibrary.login",invokeOption, parameters); return returnData; } ``` -------------------------------- ### GET Request with WebApiClient Source: https://github.com/rrqm/touchsocket/blob/master/handbook/docs/webapi-client.mdx Perform a GET request using WebApiClient. The WebApiRequest object handles URL encoding for query parameters, and InvokeTAsync returns a strongly-typed result. ```csharp var request = new WebApiRequest("/apiserver/sum") .AddQuery("a", 10) .AddQuery("b", 20); var result = await client.InvokeTAsync(request); Console.WriteLine(result); ``` -------------------------------- ### Use TouchSocketPro for Temporary Testing Source: https://github.com/rrqm/touchsocket/blob/master/handbook/docs/enterprise.mdx Utilize the Enterprise.ForTest() method for a 1-hour trial of Pro features. This method throws a controllable exception when the trial expires, which can be caught and handled. ```csharp try { Enterprise.ForTest(); } catch (Exception ex) { Console.WriteLine(ex.Message); } ``` -------------------------------- ### Create and Configure a TcpClient Source: https://context7.com/rrqm/touchsocket/llms.txt Instantiate a TcpClient, set up event handlers for connection and data reception, and configure network settings including remote host and reconnection behavior. ```csharp using TouchSocket.Core; using TouchSocket.Sockets; using System.Text; var client = new TcpClient(); client.Connected = (c, e) => { Console.WriteLine("Connected to server"); return EasyTask.CompletedTask; }; client.Closed = (c, e) => { Console.WriteLine($"Disconnected: {e.Message}"); return EasyTask.CompletedTask; }; client.Received = (c, e) => { Console.WriteLine($"Received: {Encoding.UTF8.GetString(e.Memory.Span)}"); return EasyTask.CompletedTask; }; await client.SetupAsync(new TouchSocketConfig() .SetRemoteIPHost("127.0.0.1:7789") .UseNoDelay() .ConfigureContainer(a => a.AddConsoleLogger()) .ConfigurePlugins(a => { // Auto-reconnect: polls every 3 seconds after disconnect a.UseReconnection() .SetTick(3000); })); await client.ConnectAsync(); // Send bytes await client.SendAsync(Encoding.UTF8.GetBytes("Hello Server")); // Send string (extension method) await client.SendAsync("Hello Server"); // Async-blocking receive (await directly in context) var data = await client.ReceiveAsync(); Console.WriteLine(Encoding.UTF8.GetString(data.Memory.Span)); // Pause / resume reconnection client.SetPauseReconnection(true); // pause client.SetPauseReconnection(false); // resume // ---- Inherit TcpClient to override receive ---- public class MyTcpClient : TcpClient { protected override async Task OnTcpReceived(ReceivedDataEventArgs e) { Console.WriteLine($"Override received: {Encoding.UTF8.GetString(e.Memory.Span)}"); await base.OnTcpReceived(e); } } ``` -------------------------------- ### Receive Data using Plugins Source: https://github.com/rrqm/touchsocket/blob/master/handbook/docs/namedpipeclient.mdx Implement data reception by defining and configuring plugins. This approach promotes a highly decoupled and simple way to handle data. ```csharp public class MyPlugin : PluginBase, INamedPipeReceivedPlugin { public void OnNamedPipeReceived(NamedPipeSessionClient client, ConnectionEventArgs e) { Console.WriteLine($"插件收到数据: {e.Data}"); } } var client = new NamedPipeClient(); client.PipeName = "TouchSocketPipe"; client.AddPlugin(new MyPlugin()); client.ConnectAsync(); ``` -------------------------------- ### Public Endpoint Source: https://github.com/rrqm/touchsocket/blob/master/handbook/docs/webapi-auth.mdx An example of a public endpoint that does not require any authentication. ```APIDOC ## GET /secureapiserver/publicinfo ### Description Retrieves public information that is accessible without authentication. ### Method GET ### Endpoint /secureapiserver/publicinfo ### Response #### Success Response (200) - **string** - A string containing public information. ``` -------------------------------- ### Create and Use ByteBlock Source: https://context7.com/rrqm/touchsocket/llms.txt Illustrates creating, writing primitives, and reading data from a ByteBlock. Ensure ByteBlock is disposed using 'using' or explicitly. ```csharp using TouchSocket.Core; // ---- Create and dispose ---- using var block = new ByteBlock(1024); // request at least 1024 bytes // Write primitives block.Write((int)42); block.Write((ushort)100); block.Write(Encoding.UTF8.GetBytes("Hello")); // Read back (rewind position first) block.Position = 0; int val = block.ReadInt32(); ushort len = block.ReadUInt16(); string text = Encoding.UTF8.GetString(block.ReadToSpan((int)len)); // Access effective data (Position 0 to Length) ReadOnlySpan span = block.Span; Memory mem = block.Memory; byte[] arr = block.ToArray(); // copy to managed array (safe to keep after Dispose) ``` -------------------------------- ### Create WebApiClient Source: https://github.com/rrqm/touchsocket/blob/master/handbook/docs/webapi-client.mdx Demonstrates how to instantiate and configure the WebApiClient for making API calls. ```APIDOC ## Create and Configure WebApiClient ### Description Initializes a `WebApiClient` instance, setting the remote host and configuring plugins. ### Method Instantiation and Configuration ### Usage ```csharp var client = new WebApiClient() .SetRemoteIPHost("localhost:7789") .ConfigurePlugins(plugins => { // Configure plugins here, e.g., logging, authentication }); ``` ### Configuration Options - `SetRemoteIPHost(string host)`: Sets the server address and port. - `ConfigurePlugins(Action configure)`: Configures various plugins for extended functionality. ``` -------------------------------- ### Admin Role Endpoint Source: https://github.com/rrqm/touchsocket/blob/master/handbook/docs/webapi-auth.mdx An example of an endpoint that requires specific role-based authorization (e.g., 'Admin'). ```APIDOC ## POST /secureapiserver/adminaction ### Description Executes an administrative action. Requires the user to have the 'Admin' role. ### Method POST ### Endpoint /secureapiserver/adminaction ### Response #### Success Response (200) - **string** - A string indicating the admin action was executed. ``` -------------------------------- ### User-Specific Endpoint Source: https://github.com/rrqm/touchsocket/blob/master/handbook/docs/webapi-auth.mdx An example of an endpoint that requires user authentication, typically via an Authorization header. ```APIDOC ## GET /secureapiserver/userinfo ### Description Retrieves user-specific information. Requires an 'Authorization' header for authentication. ### Method GET ### Endpoint /secureapiserver/userinfo ### Parameters #### Request Headers - **Authorization** (string) - Required - The authentication token (e.g., 'Bearer valid-token'). ### Response #### Success Response (200) - **string** - A string containing user information and the provided token. ``` -------------------------------- ### Using Generated Proxy Source: https://github.com/rrqm/touchsocket/blob/master/handbook/docs/webapi-client.mdx Demonstrates how to use the client proxy code that has been generated. ```APIDOC ## Using Generated Proxy ### Description Leverages the client proxy code generated from the server to make API calls seamlessly. ### Usage ```csharp // Assuming 'apiClient' is an instance of WebApiClient // and extension methods are generated for your API var result = await apiClient.SumAsync(10, 20); ``` ### Benefit Provides a convenient way to call WebAPI endpoints using generated extension methods, enhancing developer productivity. ``` -------------------------------- ### Browser Direct Access Source: https://github.com/rrqm/touchsocket/blob/master/handbook/docs/webapi-client.mdx Directly access WebAPI endpoints via a browser for simple GET requests. ```APIDOC ## GET /apiserver/sum ### Description Calculates the sum of two numbers. ### Method GET ### Endpoint http://localhost:7789/apiserver/sum ### Parameters #### Query Parameters - **a** (number) - Required - The first number. - **b** (number) - Required - The second number. ``` -------------------------------- ### Create TCP Client with PeriodPackageAdapter Source: https://github.com/rrqm/touchsocket/blob/master/handbook/docs/packageadapter.mdx Sets up a TCP client using PeriodPackageAdapter with a cache timeout of 1 second. Includes standard client configuration for remote host and logging. ```csharp private static async Task CreateClient() { var client = new TcpClient(); //载入配置 await client.SetupAsync(new TouchSocketConfig() .SetRemoteIPHost("127.0.0.1:7789") .SetTcpDataHandlingAdapter(() => new PeriodPackageAdapter() { CacheTimeout=TimeSpan.FromSeconds(1) }) .ConfigureContainer(a => { a.AddConsoleLogger();//添加一个日志注入 })); await client.ConnectAsync();//调用连接,当连接不成功时,会抛出异常。 client.Logger.Info("客户端成功连接"); return client; } ``` -------------------------------- ### Mqtt服务器通过插件接收所有消息 Source: https://github.com/rrqm/touchsocket/blob/master/handbook/docs/mqttservice.mdx Implement the IMqttReceivingPlugin to receive all Mqtt messages, including subscriptions, publish, and unsubscriptions. ```csharp public class MyMqttReceivingPlugin : IMqttReceivingPlugin { public int Order => 1; public Task OnMqttReceivingAsync(IMqttConnectedSocket socket, MqttMessageEventArgs e) { // e.MqttMessage can be MqttSubscribeMessage, MqttPublishMessage, MqttUnsubscribeMessage, etc. Console.WriteLine($"Received Mqtt Message: {e.MqttMessage.Type}"); return Task.CompletedTask; } } ``` -------------------------------- ### Browser JavaScript/Fetch API Source: https://github.com/rrqm/touchsocket/blob/master/handbook/docs/webapi-client.mdx Utilize JavaScript's Fetch API to make GET and POST requests to WebAPI endpoints from a browser. ```APIDOC ## GET Request with Fetch API ### Description Performs a GET request to the /apiserver/sum endpoint. ### Method GET ### Endpoint http://localhost:7789/apiserver/sum?a=10&b=20 ### Parameters #### Query Parameters - **a** (number) - Required - The first number. - **b** (number) - Required - The second number. ### Response #### Success Response (200) - **data** (any) - The JSON response from the server. ## POST Request with Fetch API ### Description Performs a POST request to the /apiserver/create endpoint with a JSON body. ### Method POST ### Endpoint http://localhost:7789/apiserver/create ### Parameters #### Request Body - **name** (string) - Required - The name to create. - **age** (number) - Required - The age to associate with the name. ### Response #### Success Response (200) - **data** (any) - The JSON response from the server. ``` -------------------------------- ### Browser JavaScript Fetch API Source: https://github.com/rrqm/touchsocket/blob/master/handbook/docs/webapi-client.mdx Make GET and POST requests to WebAPI endpoints using the browser's Fetch API. ```javascript // GET 请求 fetch('http://localhost:7789/apiserver/sum?a=10&b=20') .then(response => response.json()) .then(data => console.log(data)); // POST 请求 fetch('http://localhost:7789/apiserver/create', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ name: 'Alice', age: 25 }) }) .then(response => response.json()) .then(data => console.log(data)); ``` -------------------------------- ### 注册 RPC 接口服务 Source: https://github.com/rrqm/touchsocket/blob/master/handbook/docs/rpcregister.mdx 当服务是一个接口时,可以在 AddRpcStore 时,通过 RpcStore 实例,按注册接口与实例服务。 ```csharp public interface IMyRpcServer2 { [RpcMethod] string SayHello(string msg); } public class MyRpcServer2 : IMyRpcServer2 { public string SayHello(string msg) { return "Hello " + msg; } } ``` ```csharp builder.Services.AddTouchSocket .AddRpc("myRpcServer", socketOptions => { socketOptions.UseNewtonsoftJson(); }) .AddRpcStore(store => { store.RegisterServer(); }); ``` -------------------------------- ### Create WebSocket Client Source: https://github.com/rrqm/touchsocket/blob/master/handbook/docs/websocketclient.mdx Instantiate a WebSocketClient with basic configuration. Use the 'Received' delegate for simple data handling. ```csharp var client = new WebSocketClient(); client.Received.Add(msg => { Console.WriteLine($"收到数据:{msg.Message}"); }); await client.ConnectAsync(); ``` -------------------------------- ### Enable Disconnect Reconnection Source: https://github.com/rrqm/touchsocket/blob/master/handbook/docs/namedpipeclient.mdx Enable automatic reconnection after a disconnection. The reconnection mechanism is active after 'Setup' and relies on the 'Online' property being false. ```csharp var client = new NamedPipeClient(); client.PipeName = "TouchSocketPipe"; client.UseNamedPipeReconnection(); client.ConnectAsync(); ``` -------------------------------- ### Switch Data Handling Adapter at Runtime Source: https://context7.com/rrqm/touchsocket/llms.txt Demonstrates how to dynamically change the data handling adapter for a client connection after it has been established. ```csharp // ---- Switch adapter at runtime ---- client.SetDataHandlingAdapter(new NormalDataHandlingAdapter()); ``` -------------------------------- ### FromHeader Attribute Example Source: https://github.com/rrqm/touchsocket/blob/master/handbook/docs/webapi-parameter.mdx Bind parameters from HTTP headers using the FromHeader attribute. This is useful for passing metadata like authorization tokens. ```csharp public string SumFromHeader([FromHeader(Name = "a")] int headerA, [FromHeader(Name = "b")] int headerB) { return $"headerA={headerA}, headerB={headerB}"; } ``` -------------------------------- ### 初始化固定时间窗口限流器 Source: https://github.com/rrqm/touchsocket/blob/master/handbook/blog/tcplimiting.mdx 初始化一个固定时间窗口限流器,用于限制并发连接数。PermitLimit指定窗口内最大允许数,QueueLimit指定排队最大数,Window指定时间范围。 ```csharp private RateLimiter m_rateLimiter = new FixedWindowRateLimiter(new FixedWindowRateLimiterOptions() { PermitLimit = 2, QueueLimit = 4, Window = TimeSpan.FromSeconds(5) }); ``` -------------------------------- ### Basic Redis Usage with GetDmtpRedisActor Source: https://github.com/rrqm/touchsocket/blob/master/handbook/docs/dmtpredis.mdx Obtain a Redis actor instance using GetDmtpRedisActor() to perform cache operations like setting and getting values. ```csharp var redisActor = client.GetDmtpRedisActor(); // Set a cache value with expiration await redisActor.SetAsync("mykey", "myvalue", 10000); // Get a cache value var value = await redisActor.GetAsync("mykey"); // Add a cache item if it doesn't exist await redisActor.AddAsync("anotherkey", "anothervalue"); // Check if a key exists var exists = await redisActor.ContainsCacheAsync("mykey"); // Remove a cache item await redisActor.RemoveCacheAsync("mykey"); // Clear all cache items await redisActor.ClearCacheAsync(); ``` -------------------------------- ### 注册 RPC 服务实例 Source: https://github.com/rrqm/touchsocket/blob/master/handbook/docs/rpcregister.mdx 当服务仅是一个实例类时,可以直接在 AddRpcStore 时通过 RpcStore 实例注册服务。 ```csharp public class MyRpcServer : ServiceBase { [RpcMethod] public string SayHello(string msg) { return "Hello " + msg; } } ``` ```csharp builder.Services.AddTouchSocket .AddRpc("myRpcServer", socketOptions => { socketOptions.UseNewtonsoftJson(); }) .AddRpcStore(store => { store.RegisterServer(); }); ``` -------------------------------- ### Configure AspNetCore Unified Container Source: https://github.com/rrqm/touchsocket/blob/master/handbook/docs/dmtpservice.mdx Use ConfigureContainer to unify the configuration of all components within the AspNetCore Host. This ensures consistent setup across the application. ```csharp builder.ConfigureContainer((context, containerBuilder) => { // Add your registrations here }); ``` -------------------------------- ### Simplify WebSocket Connection (3.x to 4.0) Source: https://github.com/rrqm/touchsocket/blob/master/handbook/src/pages/upgrade/upgrade-to-4-0.mdx For simple connections, use the ConnectAsync(url) method directly instead of SetupAsync followed by ConnectAsync. ```csharp var client = new WebSocketClient(); await client.SetupAsync(new TouchSocketConfig() .SetRemoteIPHost("ws://127.0.0.1:7789/ws")); await client.ConnectAsync(); ``` ```csharp var client = new WebSocketClient(); await client.ConnectAsync("ws://127.0.0.1:7789/ws"); ``` -------------------------------- ### FromHeader - Get parameter from request header Source: https://github.com/rrqm/touchsocket/blob/master/handbook/docs/webapi-parameter.mdx Bind parameters directly from HTTP request headers. The `Name` attribute can be used to specify a custom header name. ```APIDOC ## GET /ApiServer/SumFromHeader ### Description This endpoint retrieves two integer values from request headers. ### Method GET ### Endpoint /ApiServer/SumFromHeader ### Parameters #### Path Parameters - **a** (int) - Required - The first integer value, expected in the 'a' header. - **b** (int) - Required - The second integer value, expected in the 'b' header. ``` -------------------------------- ### Custom DmtpRpc Serialization Configuration Source: https://github.com/rrqm/touchsocket/blob/master/handbook/docs/dmtprpc.mdx Implement custom serialization by creating a class that implements the ISerializationConverter interface. This example demonstrates using MemoryPack for custom serialization. ```csharp ``` -------------------------------- ### Create TcpService Source: https://github.com/rrqm/touchsocket/blob/master/handbook/docs/tcpservice.mdx Initialize a TcpService with default settings. Handle basic logic via delegates like Connecting, Connected, and Received. ```csharp var service = new TcpService(); service.Connecting += (client, arg) => { // Handle connection attempt }; service.Connected += (client, arg) => { // Handle successful connection }; service.Received += (client, arg) => { // Handle received data }; await service.StartAsync(10000); Console.WriteLine("服务器启动成功,按任意键退出..."); Console.ReadKey(); ``` -------------------------------- ### Use ValueByteBlock and Custom Pool Source: https://context7.com/rrqm/touchsocket/llms.txt Demonstrates using ValueByteBlock for stack-allocated headers and heap bodies, and how to create a custom memory pool for ByteBlock. ```csharp // ---- ValueByteBlock (stack-allocated header, heap body) ---- using var vblock = new ValueByteBlock(256); vblock.Write((byte)0xFF); Console.WriteLine(vblock.Length); // 1 // ---- Custom pool ---- var pool = ArrayPool.Create(maxArrayLength: 1024 * 1024, maxArraysPerBucket: 50); using var pooled = new ByteBlock(pool, 512); ``` -------------------------------- ### FromForm - Get parameter from form data Source: https://github.com/rrqm/touchsocket/blob/master/handbook/docs/webapi-parameter.mdx Bind parameters from form data, typically used with `application/x-www-form-urlencoded` or `multipart/form-data` content types. Supports file uploads with `multipart/form-data`. ```APIDOC ## GET /ApiServer/SumFromForm ### Description This endpoint retrieves two integer values from form data. ### Method GET ### Endpoint /ApiServer/SumFromForm ### Parameters #### Query Parameters - **a** (int) - Required - The first integer value, expected in the form data. - **b** (int) - Required - The second integer value, expected in the form data. ``` -------------------------------- ### FromForm Attribute Example Source: https://github.com/rrqm/touchsocket/blob/master/handbook/docs/webapi-parameter.mdx Use the FromForm attribute to bind parameters from form data. This is typically used with POST requests and supports Content-Types like application/x-www-form-urlencoded and multipart/form-data. ```csharp public string SumFromForm([FromForm(Name = "a")] int formA, [FromForm(Name = "b")] int formB) { return $"formA={formA}, formB={formB}"; } ``` -------------------------------- ### Deploy Website Using SSH Source: https://github.com/rrqm/touchsocket/blob/master/handbook/README.md Deploys the website using SSH. Assumes SSH is configured for deployment. ```bash $ USE_SSH=true yarn deploy ``` -------------------------------- ### FromQuery Attribute Example Source: https://github.com/rrqm/touchsocket/blob/master/handbook/docs/webapi-parameter.mdx Use the FromQuery attribute to explicitly bind parameters from the URL's query string. You can customize the parameter name using the 'Name' property. ```csharp public string SumFromQuery(int a, [FromQuery(Name = "aa")] int b) { return $"a={a}, b={b}"; } ``` -------------------------------- ### Create Service with JsonPackageAdapter Source: https://github.com/rrqm/touchsocket/blob/master/handbook/docs/packageadapter.mdx Sets up and starts a TCP service that uses the JsonPackageAdapter to handle incoming JSON data. It defines a 'Received' event handler to process the JSON packages. ```csharp private static async Task CreateService() { var service = new TcpService(); service.Received = (client, e) => { //从客户端收到信息 if (e.RequestInfo is JsonPackage jsonPackage) { StringBuilder sb = new StringBuilder(); sb.Append($"已从{client.Id}接收到数据。"); sb.Append($"数据类型:{jsonPackage.Kind},"); sb.Append($"数据:{jsonPackage.DataString},"); sb.Append($"杂质数据:{jsonPackage.ImpurityData.Span.ToString(Encoding.UTF8)}"); client.Logger.Info(sb.ToString()); } return Task.CompletedTask; }; await service.SetupAsync(new TouchSocketConfig()//载入配置 .SetListenIPHosts("tcp://127.0.0.1:7789", 7790)//同时监听两个地址 .SetTcpDataHandlingAdapter(()=>new JsonPackageAdapter(Encoding.UTF8)) .ConfigureContainer(a => { a.AddConsoleLogger();//添加一个控制台日志注入(注意:在maui中控制台日志不可用) }) .ConfigurePlugins(a => { //a.Add();//此处可以添加插件 })); await service.StartAsync();//启动 service.Logger.Info("服务器已启动"); return service; } ``` -------------------------------- ### Connect and Send with TcpClient Source: https://github.com/rrqm/touchsocket/blob/master/README.md Set up a TCP client to connect to a server, handle connection events, and send data. The client can also be configured with event handlers for connection, disconnection, and message reception. ```csharp TcpClient client = new TcpClient(); client.Connected = (c, e) => EasyTask.CompletedTask; client.Closed = (c, e) => EasyTask.CompletedTask; client.Received = (c, e) => { Console.WriteLine(e.Memory.Span.ToString()); return EasyTask.CompletedTask; }; await client.ConnectAsync("127.0.0.1:7789"); await client.SendAsync("Hello"); ``` -------------------------------- ### Mqtt服务器接收发布消息 Source: https://github.com/rrqm/touchsocket/blob/master/handbook/docs/mqttservice.mdx Implement the IMqttReceivedPlugin to specifically receive successful Mqtt publish messages. ```csharp public class MyMqttReceivedPlugin : IMqttReceivedPlugin { public int Order => 1; public Task OnMqttReceivedAsync(IMqttConnectedSocket socket, MqttMessageEventArgs e) { // e.MqttMessage is MqttPublishMessage Console.WriteLine($"Received Publish Message: {e.MqttMessage.Topic}"); return Task.CompletedTask; } } ``` -------------------------------- ### FromBody - Get parameter from request body Source: https://github.com/rrqm/touchsocket/blob/master/handbook/docs/webapi-parameter.mdx Explicitly bind a parameter from the request body, typically used for complex types and JSON payloads. The content type is usually `application/json`. ```APIDOC ## POST /ApiServer/TestPost ### Description This endpoint accepts a JSON object in the request body and processes it. ### Method POST ### Endpoint /ApiServer/TestPost ### Parameters #### Request Body - **a** (int) - Required - The first integer property of the JSON object. - **b** (int) - Required - The second integer property of the JSON object. ``` -------------------------------- ### HTTP JSON-RPC Call Example (curl equivalent) Source: https://context7.com/rrqm/touchsocket/llms.txt Illustrates an HTTP POST request to a JSON-RPC endpoint. The `Content-Type` must be `application/json`, and the body follows the JSON-RPC 2.0 specification. ```http POST http://localhost:9902/jsonrpc Content-Type: application/json Body: {"jsonrpc":"2.0","method":"Add","params":[3,4],"id":1} Response: {"jsonrpc":"2.0","result":7,"id":1} ```