Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

History

305 Commits

Repository files navigation

WebSocketServer

996ICUVersionNuGetBuildCode SizeLicense
996.icuNuGetCode sizeLicenseLICENSE

WebSocketServer is a lightweight and high-performance WebSocket library. Supports routing, full-duplex communication, clustering, and multi-language client SDKs.

📚 Documentation Center / 文档中心

✨ Features / 特性

  • Lightweight & High Performance - Based on ASP.NET Core
  • Routing System - MVC-like routing mechanism
  • Full Duplex Communication - Bidirectional communication support
  • Multi-node Cluster - Raft-based consensus protocol
  • Multi-language Clients - C#, TypeScript, Rust, Java, Dart, Python
  • Automatic Endpoint Discovery - Client SDKs auto-discover server endpoints
  • Streaming Upload - [WebSocket(Stream = true)] streams large files with constant server memory / 大文件流式上传,服务端内存恒定
  • Receive Memory Control - Per-connection / per-endpoint / global receive caps, safe by default / 三级接收内存封顶,默认即安全
  • Dashboard - Real-time monitoring and statistics

QuickStart

1. Install Library / 安装库

# Package Manager
Install-Package Cyaim.WebSocketServer
# .NET CLI
dotnet add package Cyaim.WebSocketServer
# PackageReference<PackageReference Include="Cyaim.WebSocketServer" Version="2.0.0" />

2. Configure WebSocket Server / 配置 WebSocket 服务器

Using Minimal API / 使用 Minimal API

Two lines are all you need — AddWebSocketServer() automatically wires an MvcChannelHandler on channel /ws and discovers all [WebSocket] endpoints in your *.Controllers namespace.
只需两行代码 —— AddWebSocketServer() 会自动在 /ws 通道上挂载 MvcChannelHandler,并自动发现 *.Controllers 命名空间下所有标记了 [WebSocket] 的终结点。

usingCyaim.WebSocketServer.Infrastructure;usingCyaim.WebSocketServer.Middlewares;varbuilder=WebApplication.CreateBuilder(args);// Add WebSocket server (default channel: /ws) / 添加 WebSocket 服务器(默认通道:/ws)builder.Services.AddWebSocketServer();varapp=builder.Build();app.UseWebSockets();app.UseWebSocketServer();app.Run();

Need more channels or options? Use the fluent builder or the configure overload:
需要更多通道或配置?使用流式构建器或配置重载:

// Custom channels / 自定义通道builder.Services.AddWebSocketServer().AddMvcChannel("/im")// MVC-style channel / MVC 风格通道.AddChannel("/chat",myHandler.ConnectionEntry);// Custom handler / 自定义处理器// Note: explicitly adding channels replaces the auto default "/ws".// 注意:显式添加通道会替换自动默认的 "/ws" 通道。// Custom options / 自定义配置builder.Services.AddWebSocketServer(x =>{x.MaxConnectionLimit=10000;x.WatchAssemblyNamespacePrefix="MyApp.WsControllers";// Endpoint scan prefix / 终结点扫描前缀});

Using Startup.cs / 使用 Startup.cs

publicvoidConfigureServices(IServiceCollectionservices){services.AddWebSocketServer();}publicvoidConfigure(IApplicationBuilderapp,IWebHostEnvironmentenv){app.UseWebSockets();app.UseWebSocketServer();}

Advanced: Manual Configuration / 高级:手动配置

ConfigureWebSocketRoute remains fully supported when you want full manual control (channel table, service collection, etc.):
当您需要完全手动控制(通道表、服务容器等)时,仍可使用 ConfigureWebSocketRoute

usingCyaim.WebSocketServer.Infrastructure.Handlers.MvcHandler;usingCyaim.WebSocketServer.Infrastructure.Configures;usingCyaim.WebSocketServer.Middlewares;varbuilder=WebApplication.CreateBuilder(args);// Configure WebSocket route manually / 手动配置 WebSocket 路由builder.Services.ConfigureWebSocketRoute(x =>{varmvcHandler=newMvcChannelHandler();x.WebSocketChannels=newDictionary<string,WebSocketRouteOption.WebSocketChannelHandler>(){{"/ws",mvcHandler.ConnectionEntry}};x.ApplicationServiceCollection=builder.Services;});varapp=builder.Build();// Configure WebSocket options / 配置 WebSocket 选项varwebSocketOptions=newWebSocketOptions(){KeepAliveInterval=TimeSpan.FromSeconds(120),};app.UseWebSockets(webSocketOptions);app.UseWebSocketServer();app.Run();

3. Mark WebSocket Endpoints / 标记 WebSocket 端点

Add [WebSocket] attribute to your controller actions:

[ApiController][Route("[controller]")]publicclassWeatherForecastController:ControllerBase{[WebSocket]// Mark as WebSocket endpoint / 标记为 WebSocket 端点[HttpGet]publicIEnumerable<WeatherForecast>Get(){varrng=newRandom();returnEnumerable.Range(1,5).Select(index =>newWeatherForecast{Date=DateTime.Now.AddDays(index),TemperatureC=rng.Next(-20,55),Summary=Summaries[rng.Next(Summaries.Length)]}).ToArray();}}

Note: The target parameter in requests is case-insensitive.
注意: 请求中的 target 参数不区分大小写。

Request and Response

Scheme namespace 👇
Request Cyaim.WebSocketServer.Infrastructure.Handlers.MvcRequestScheme
Response Cyaim.WebSocketServer.Infrastructure.Handlers.MvcResponseScheme

Request target ignore case

Request scheme

1. Nonparametric method request

{
"target": "WeatherForecast.Get",
"body": {}
}

This request will be located at "WeatherForecastController" -> "Get" Method.

Response to this request

{
"Target": "WeatherForecast.Get""Status": 0,
"Msg": null,
"RequestTime": 637395762382112345,
"CompleteTime": 637395762382134526,
"Body": [{
"Date": "2020-10-30T13:50:38.2133285+08:00",
"TemperatureC": 43,
"TemperatureF": 109,
"Summary": "Scorching"
}, {
"Date": "2020-10-31T13:50:38.213337+08:00",
"TemperatureC": 1,
"TemperatureF": 33,
"Summary": "Chilly"
}]
}

Forward invoke method return content will write MvcResponseScheme.Body.

2. Request with parameters

Example Code:

  1. Change method code to:
[WebSocket][HttpGet]publicIEnumerable<WeatherForecast>Get(Testa){varrng=newRandom();returnEnumerable.Range(1,2).Select(index =>newWeatherForecast{TemperatureC=a.PreTemperatureC+rng.Next(-20,55),Summary=a.PreSummary+Summaries[rng.Next(Summaries.Length)]}).ToArray();}
  1. Define parameter class
publicclassTest{publicstringPreSummary{get;set;}publicintPreTemperatureC{get;set;}}

Request parameter

{
"target": "WeatherForecast.Get",
"body": {
"PreSummary":"Cyaim_",
"PreTemperatureC":233
}
}

Request body will be deserialized and passed to the method parameter.

Response to this request

{
"Target": "WeatherForecast.Get",
"Status": 0,
"Msg": null,
"RequestTime": 0,
"CompleteTime": 637395922139434966,
"Body": [{
"Date": "0001-01-01T00:00:00",
"TemperatureC": 282,
"TemperatureF": 539,
"Summary": "Cyaim_Warm"
}, {
"Date": "0001-01-01T00:00:00",
"TemperatureC": 285,
"TemperatureF": 544,
"Summary": "Cyaim_Sweltering"
}]
}

Client SDKs / 客户端 SDK

We provide multi-language client SDKs with automatic endpoint discovery:

Quick Example / 快速示例

C# Client:

usingCyaim.WebSocketServer.Client;varfactory=newWebSocketClientFactory("http://localhost:5000","/ws");varclient=awaitfactory.CreateClientAsync<IWeatherService>();varforecasts=awaitclient.GetForecastsAsync();

TypeScript Client:

import{WebSocketClientFactory}from'@cyaim/websocket-client';constfactory=newWebSocketClientFactory('http://localhost:5000','/ws');constclient=awaitfactory.createClient<IWeatherService>({getForecasts: async()=>{}});constforecasts=awaitclient.getForecasts();

For more details, see: Clients Documentation | 客户端文档

Streaming Upload & Memory Control / 流式上传与接收内存控制

Ordinary endpoints buffer each message (default cap 4 MiB, configurable via MaxRequestReceiveDataLimit or per-endpoint [WebSocket(MaxBytes = N)]). To transfer large files, mark the endpoint Stream = true — the payload is fed to your endpoint as a Streamwithout buffering, so server memory stays constant.
普通端点会整条缓冲消息(默认上限 4 MiB,可用 MaxRequestReceiveDataLimit 或端点级 [WebSocket(MaxBytes = N)] 调整)。要传大文件,把端点标成 Stream = true,负载会作为 Stream边收边喂给端点,服务端内存恒定。

// Server: a streaming upload endpoint / 服务端:流式上传端点[WebSocket("file.upload",Stream=true,MaxBytes=2L*1024*1024*1024)]publicasyncTask<object>Upload(UploadMetameta,Streambody,CancellationTokenct){awaitusingvarfs=File.Create(Path.Combine(dir,meta.FileName));awaitbody.CopyToAsync(fs,ct);// constant memory, end-to-end backpressurereturnnew{bytes=fs.Length};}
// Client: upload with the uploadStream helper (all 6 SDKs provide one) / 客户端:uploadStream 帮助方法constres=awaitclient.uploadStream("file.upload",fs.createReadStream("big.bin"),{fileName: "big.bin"});

⚠️2.0 behaviour change: MaxRequestReceiveDataLimit now defaults to 4 MiB (was unlimited). If you send single messages larger than 4 MiB through ordinary endpoints, raise it (or set null), or use a streaming endpoint. / 2.0 行为变更:该上限默认从"不限"改为 4 MiB,大消息需显式调大或改用流式端点。

For more details, see: Streaming Upload & Memory Control | 流式上传与内存控制

Cluster / 集群

Cyaim.WebSocketServer supports multi-node clustering with Raft consensus protocol. You can use WebSocket, Redis, or RabbitMQ for inter-node communication.

Basic Cluster Setup / 基础集群配置

usingCyaim.WebSocketServer.Infrastructure.Cluster;usingCyaim.WebSocketServer.Infrastructure.Configures;varbuilder=WebApplication.CreateBuilder(args);// Configure WebSocket route / 配置 WebSocket 路由builder.Services.ConfigureWebSocketRoute(x =>{varmvcHandler=newMvcChannelHandler();x.WebSocketChannels=newDictionary<string,WebSocketRouteOption.WebSocketChannelHandler>(){{"/ws",mvcHandler.ConnectionEntry}};x.ApplicationServiceCollection=builder.Services;});varapp=builder.Build();// Configure WebSocket / 配置 WebSocketapp.UseWebSockets();app.UseWebSocketServer(serviceProvider =>{// Configure cluster / 配置集群varclusterOption=newClusterOption{NodeId="node1",NodeAddress="localhost",NodePort=5000,TransportType="ws",// or "redis" or "rabbitmq"ChannelName="/cluster",Nodes=new[]{"ws://localhost:5001/node2","ws://localhost:5002/node3"}};returnclusterOption;});app.Run();

Using Redis Transport / 使用 Redis 传输

# Install Redis transport package / 安装 Redis 传输包
dotnet add package Cyaim.WebSocketServer.Cluster.StackExchangeRedis
varclusterOption=newClusterOption{NodeId="node1",TransportType="redis",RedisConnectionString="localhost:6379",ChannelName="/cluster",Nodes=new[]{"node1","node2","node3"}};

Using RabbitMQ Transport / 使用 RabbitMQ 传输

# Install RabbitMQ transport package / 安装 RabbitMQ 传输包
dotnet add package Cyaim.WebSocketServer.Cluster.RabbitMQ
varclusterOption=newClusterOption{NodeId="node1",TransportType="rabbitmq",RabbitMQConnectionString="amqp://guest:guest@localhost:5672/",ChannelName="/cluster",Nodes=new[]{"node1","node2","node3"}};

For more details, see: Cluster Documentation | 集群文档

📖 More Documentation / 更多文档

🔗 Related Links / 相关链接

📄 License / 许可证

This project is licensed under MIT License.

Copyright © Cyaim Studio

About

WebSocketServer is lightweight and high performance WebSocket library.support route, full duplex communication.

Resources

Stars

9 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages