WebSocketServer is lightweight and high performance WebSocket server library. Support route, full duplex communication, multiplexing, pipeline, encryption. WebSocketServer 是一个轻量级、高性能WebSocket服务端库。支持 WebApi 路由、全双工通信、多路复用、管道、加密等。
$ dotnet add package Cyaim.WebSocketServer| 996ICU | Version | NuGet | Build | Code Size | License |
|---|---|---|---|---|---|
WebSocketServer is a lightweight and high-performance WebSocket library. Supports routing, full-duplex communication, clustering, and multi-language client SDKs.
# Package Manager
Install-Package Cyaim.WebSocketServer
# .NET CLI
dotnet add package Cyaim.WebSocketServer
# PackageReference
<PackageReference Include="Cyaim.WebSocketServer" Version="1.7.8" />
using Cyaim.WebSocketServer.Infrastructure.Handlers.MvcHandler;
using Cyaim.WebSocketServer.Middlewares;
var builder = WebApplication.CreateBuilder(args);
// Configure WebSocket route / 配置 WebSocket 路由
builder.Services.ConfigureWebSocketRoute(x =>
{
var mvcHandler = new MvcChannelHandler();
x.WebSocketChannels = new Dictionary<string, WebSocketRouteOption.WebSocketChannelHandler>()
{
{ "/ws", mvcHandler.ConnectionEntry }
};
x.ApplicationServiceCollection = builder.Services;
});
var app = builder.Build();
// Configure WebSocket options / 配置 WebSocket 选项
var webSocketOptions = new WebSocketOptions()
{
KeepAliveInterval = TimeSpan.FromSeconds(120),
};
app.UseWebSockets(webSocketOptions);
app.UseWebSocketServer();
app.Run();
public void ConfigureServices(IServiceCollection services)
{
services.ConfigureWebSocketRoute(x =>
{
var mvcHandler = new MvcChannelHandler();
x.WebSocketChannels = new Dictionary<string, WebSocketRouteOption.WebSocketChannelHandler>()
{
{ "/ws", mvcHandler.ConnectionEntry }
};
x.ApplicationServiceCollection = services;
});
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
var webSocketOptions = new WebSocketOptions()
{
KeepAliveInterval = TimeSpan.FromSeconds(120),
};
app.UseWebSockets(webSocketOptions);
app.UseWebSocketServer();
}
Add [WebSocket] attribute to your controller actions:
[ApiController]
[Route("[controller]")]
public class WeatherForecastController : ControllerBase
{
[WebSocket] // Mark as WebSocket endpoint / 标记为 WebSocket 端点
[HttpGet]
public IEnumerable<WeatherForecast> Get()
{
var rng = new Random();
return Enumerable.Range(1, 5).Select(index => new WeatherForecast
{
Date = DateTime.Now.AddDays(index),
TemperatureC = rng.Next(-20, 55),
Summary = Summaries[rng.Next(Summaries.Length)]
}).ToArray();
}
}
Note: The
targetparameter in requests is case-insensitive.
注意: 请求中的target参数不区分大小写。
Scheme namespace 👇
Request Cyaim.WebSocketServer.Infrastructure.Handlers.MvcRequestScheme
Response Cyaim.WebSocketServer.Infrastructure.Handlers.MvcResponseScheme
Request target ignore case
Request scheme
{
"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.
Example Code:
[WebSocket]
[HttpGet]
public IEnumerable<WeatherForecast> Get(Test a)
{
var rng = new Random();
return Enumerable.Range(1, 2).Select(index => new WeatherForecast
{
TemperatureC = a.PreTemperatureC + rng.Next(-20, 55),
Summary = a.PreSummary + Summaries[rng.Next(Summaries.Length)]
}).ToArray();
}
public class Test
{
public string PreSummary { get; set; }
public int PreTemperatureC { 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"
}]
}
We provide multi-language client SDKs with automatic endpoint discovery:
C# Client:
using Cyaim.WebSocketServer.Client;
var factory = new WebSocketClientFactory("http://localhost:5000", "/ws");
var client = await factory.CreateClientAsync<IWeatherService>();
var forecasts = await client.GetForecastsAsync();
TypeScript Client:
import { WebSocketClientFactory } from '@cyaim/websocket-client';
const factory = new WebSocketClientFactory('http://localhost:5000', '/ws');
const client = await factory.createClient<IWeatherService>({
getForecasts: async () => {}
});
const forecasts = await client.getForecasts();
For more details, see: Clients Documentation | 客户端文档
Cyaim.WebSocketServer supports multi-node clustering with Raft consensus protocol. You can use WebSocket, Redis, or RabbitMQ for inter-node communication.
using Cyaim.WebSocketServer.Infrastructure.Cluster;
using Cyaim.WebSocketServer.Infrastructure.Configures;
var builder = WebApplication.CreateBuilder(args);
// Configure WebSocket route / 配置 WebSocket 路由
builder.Services.ConfigureWebSocketRoute(x =>
{
var mvcHandler = new MvcChannelHandler();
x.WebSocketChannels = new Dictionary<string, WebSocketRouteOption.WebSocketChannelHandler>()
{
{ "/ws", mvcHandler.ConnectionEntry }
};
x.ApplicationServiceCollection = builder.Services;
});
var app = builder.Build();
// Configure WebSocket / 配置 WebSocket
app.UseWebSockets();
app.UseWebSocketServer(serviceProvider =>
{
// Configure cluster / 配置集群
var clusterOption = new ClusterOption
{
NodeId = "node1",
NodeAddress = "localhost",
NodePort = 5000,
TransportType = "ws", // or "redis" or "rabbitmq"
ChannelName = "/cluster",
Nodes = new[]
{
"ws://localhost:5001/node2",
"ws://localhost:5002/node3"
}
};
return clusterOption;
});
app.Run();
# Install Redis transport package / 安装 Redis 传输包
dotnet add package Cyaim.WebSocketServer.Cluster.StackExchangeRedis
var clusterOption = new ClusterOption
{
NodeId = "node1",
TransportType = "redis",
RedisConnectionString = "localhost:6379",
ChannelName = "/cluster",
Nodes = new[] { "node1", "node2", "node3" }
};
# Install RabbitMQ transport package / 安装 RabbitMQ 传输包
dotnet add package Cyaim.WebSocketServer.Cluster.RabbitMQ
var clusterOption = new ClusterOption
{
NodeId = "node1",
TransportType = "rabbitmq",
RabbitMQConnectionString = "amqp://guest:guest@localhost:5672/",
ChannelName = "/cluster",
Nodes = new[] { "node1", "node2", "node3" }
};
For more details, see: Cluster Documentation | 集群文档
This project is licensed under MIT License.
Copyright © Cyaim Studio