电流的
用于的现代轻量级JSON-RPC 2.0和MCP实现。NET 8.0和。净值10.0
Voltaic为JSON-RPC 2.0和模型上下文协议(MCP)提供客户端和服务器实现。无论您是构建微服务、人工智能集成还是分布式系统,Voltaic都能为您提供清晰可靠的通信工具。
______________________________________________________________________
里面是什么
JSON-RPC 2.0
基于TCP的客户端和服务器的完整JSON-RPC 2.0实现。非常适合构建基于RPC的API、微服务和分布式应用程序。
特征:
- 完全符合JSON-RPC 2.0规范
- 基于TCP的LSP式消息帧传输(
Content-Length标题) - 异步/等待现代。网具性能
- 支持请求、响应、通知和广播
- 类型安全的方法注册和调用
- 连接管理,优雅关机
- 线程安全并发请求处理
- 具有连接和请求/响应事件的事件驱动架构
- 具有可配置限制的每客户端通知队列管理
模型上下文协议(MCP)
Anthropic模型上下文协议的客户端和服务器实现,支持多种传输选项。
特征:
- 标准运输:基于子进程的MCP服务器(标准MCP模式)
- TCP传输:基于网络的MCP通信,采用LSP式框架
- HTTP传输:基于HTTP的MCP与服务器发送事件(SSE)通信以获取通知
- WebSocket传输:全双工双向通信
- 在所有传输中实现JSON-RPC 2.0协议
- 子流程服务器的流程生命周期管理
- 基于连接生命周期事件的事件驱动通知处理
- 具有时间信息的请求/响应事件跟踪
- 与MCP服务器生态系统兼容
认证
McpHttpServer 支持在任何请求处理之前运行的可选异步身份验证处理程序。设置后,每个传入的HTTP请求都会通过处理程序传递,处理程序会接收完整的 HttpListenerRequest 并返回一个 AuthenticationResult如果身份验证失败,服务器将返回配置的HTTP状态码和错误消息,而不处理请求。如果未设置,则接受所有请求(保持向后兼容性)。
using System.Net;
using Voltaic;
McpHttpServer server = new McpHttpServer("localhost", 8080);
server.AuthenticationHandler = async (HttpListenerRequest request) =>
{
string? token = request.Headers["Authorization"];
if (string.IsNullOrEmpty(token) || !token.StartsWith("Bearer "))
{
return new AuthenticationResult
{
IsAuthenticated = false,
StatusCode = 401,
ErrorMessage = "Missing or invalid Authorization header"
};
}
// Validate the token (call your JWT validation, database lookup, etc.)
bool isValid = await ValidateTokenAsync(token.Substring("Bearer ".Length));
return new AuthenticationResult
{
IsAuthenticated = isValid,
Principal = "my-user",
Claims = new Dictionary { { "role", "admin" } }
};
};
await server.StartAsync();以下端点始终绕过身份验证,允许在没有凭据的情况下进行连接验证:
- 健康检查 (
GET /)--退货{"status":"Ok"},可用于负载平衡器探测 - 拼 (
pingJSON-RPC方法通过任何RPC端点)--返回"pong",验证应用层连接 - 跨域资源共享预检 (
OPTIONS请求)--返回204带有CORS标头
当身份验证失败时,所有其他请求都会被拒绝,并显示配置的状态代码和错误消息。
完整的授权流程(如OAuth 2.1,如 MCP规范)仍然是应用程序开发人员的责任。这 AuthenticationHandler 为集成任何身份验证方案提供了挂钩点。
______________________________________________________________________
这是给谁的?
Voltaic专为需要以下功能的开发人员而设计:
- 微服务通信:构建使用标准RPC协议相互通信的服务
- AI工具集成:连接到MCP服务器进行AI助手集成(Claude等)
- 自定义RPC API:实现自己的远程过程调用接口
- 子流程编排:使用stdio传输启动子进程并与之通信
- 语言服务器协议:构建使用Content-Length框架的LSP风格应用程序
- 实时系统:TCP套接字上的低延迟RPC通信
- 基于Web的集成:用于浏览器兼容通信的HTTP和WebSocket传输
- 灵活的运输方式:为您的建筑选择合适的运输方式
如果你在建。NET应用程序需要结构化的双向通信,Voltaic为您提供了解决方案。
______________________________________________________________________
入门指南
安装
# Install the Voltaic package
dotnet add package Voltaic快速入门:JSON-RPC服务器(TCP)
using System.Net;
using System.Text.Json;
using Voltaic;
JsonRpcServer server = new JsonRpcServer(IPAddress.Any, 8080);
// Subscribe to events
server.ClientConnected += (sender, client) =>
Console.WriteLine($"Client connected: {client.SessionId}");
server.RequestReceived += (sender, e) =>
Console.WriteLine($"Request: {e.Method} from {e.Client.SessionId}");
server.ResponseSent += (sender, e) =>
Console.WriteLine($"Response: {e.Method} took {e.Duration.TotalMilliseconds}ms");
// Register a synchronous method
server.RegisterMethod("greet", (JsonElement? args) =>
{
string? name = args?.TryGetProperty("name", out JsonElement nameEl) == true
? nameEl.GetString()
: "World";
return $"Hello, {name}!";
});
// Register an asynchronous method (for I/O-bound work like DB queries, HTTP calls, etc.)
server.RegisterMethod("fetchData", async (JsonElement? args) =>
{
// Async handlers avoid blocking the thread pool
await Task.Delay(100); // Simulate async work
return (object)"async result";
});
// Register an async method with cancellation support
server.RegisterMethod("longRunningTask", async (JsonElement? args, CancellationToken token) =>
{
// The token is the server's connection processing token
await Task.Delay(5000, token); // Cancels if client disconnects
return (object)"completed";
});
// Start the server
await server.StartAsync();
Console.WriteLine("Server running on port 8080");
// Keep it running
await Task.Delay(Timeout.Infinite, server.TokenSource.Token);快速入门:JSON-RPC客户端(TCP)
using Voltaic;
JsonRpcClient client = new JsonRpcClient();
// Subscribe to notification events from server
client.NotificationReceived += (sender, request) =>
Console.WriteLine($"Server notification: {request.Method}");
await client.ConnectAsync("localhost", 8080);
// Call a method with typed response
string greeting = await client.CallAsync("greet", new { name = "Developer" });
Console.WriteLine(greeting); // "Hello, Developer!"
// Send a notification (no response expected)
await client.NotifyAsync("logEvent", new { level = "info", message = "User logged in" });快速入门:MCP服务器(stdio)
using System.Text.Json;
using Voltaic;
McpServer server = new McpServer();
// Customize server identity (optional)
server.ServerName = "MyMcpServer";
server.ServerVersion = "2.0.0";
// Register a tool with metadata for MCP tool discovery
server.RegisterTool("add",
"Adds two numbers",
new
{
type = "object",
properties = new
{
a = new { type = "number", description = "First number" },
b = new { type = "number", description = "Second number" }
},
required = new[] { "a", "b" }
},
(JsonElement? args) =>
{
double a = args?.TryGetProperty("a", out JsonElement aEl) == true ? aEl.GetDouble() : 0;
double b = args?.TryGetProperty("b", out JsonElement bEl) == true ? bEl.GetDouble() : 0;
return (object)(a + b);
});
// Built-in methods are registered automatically:
// - initialize (returns capabilities and serverInfo)
// - tools/list (returns all registered tools)
// - tools/call (invokes a tool by name)
// - notifications/initialized (handles client init notification)
// - ping, echo, getTime (utility tools)
// Run the server (reads from stdin, writes to stdout)
await server.RunAsync();快速入门:MCP客户端(stdio)
using Voltaic;
McpClient client = new McpClient();
// Launch an MCP server as a subprocess
await client.LaunchServerAsync("dotnet", new[] { "run", "--project", "MyMcpServer" });
// Call methods on the server
JsonRpcResponse response = await client.CallAsync("tools/list");
Console.WriteLine(response.Result);快速入门:MCP服务器(TCP)
using System.Net;
using System.Text.Json;
using Voltaic;
McpTcpServer server = new McpTcpServer(IPAddress.Any, 8080);
// Subscribe to events
server.ClientConnected += (sender, client) =>
Console.WriteLine($"Client connected: {client.SessionId}");
server.ClientDisconnected += (sender, client) =>
Console.WriteLine($"Client disconnected: {client.SessionId}");
// Register a method (tools/call dispatches to registered methods by name)
server.RegisterMethod("add", (JsonElement? args) =>
{
double a = args?.TryGetProperty("a", out JsonElement aEl) == true ? aEl.GetDouble() : 0;
double b = args?.TryGetProperty("b", out JsonElement bEl) == true ? bEl.GetDouble() : 0;
return (object)(a + b);
});
// Register tools/list so clients can discover available tools
server.RegisterMethod("tools/list", (JsonElement? args) =>
{
return new
{
tools = new[]
{
new
{
name = "add",
description = "Adds two numbers",
inputSchema = new
{
type = "object",
properties = new
{
a = new { type = "number", description = "First number" },
b = new { type = "number", description = "Second number" }
},
required = new[] { "a", "b" }
}
}
}
};
});
// Start the server
await server.StartAsync();
Console.WriteLine("MCP server running on port 8080");
await Task.Delay(Timeout.Infinite, server.TokenSource.Token);快速入门:MCP客户端(TCP)
using Voltaic;
McpTcpClient client = new McpTcpClient();
// Subscribe to server notifications
client.NotificationReceived += (sender, request) =>
Console.WriteLine($"Server notification: {request.Method}");
// Connect to the TCP server
await client.ConnectAsync("localhost", 8080);
// Call methods on the server
object? tools = await client.CallAsync("tools/list");
Console.WriteLine(tools);快速入门:MCP服务器(HTTP)
using System.Text.Json;
using Voltaic;
McpHttpServer server = new McpHttpServer("localhost", 8080);
// Subscribe to events
server.ClientConnected += (sender, client) =>
Console.WriteLine($"Session started: {client.SessionId}");
server.RequestReceived += (sender, e) =>
Console.WriteLine($"Request: {e.Method} from session {e.Client.SessionId}");
// Register a tool (automatically added to tools/list and tools/call)
server.RegisterTool("add",
"Adds two numbers",
new
{
type = "object",
properties = new
{
a = new { type = "number", description = "First number" },
b = new { type = "number", description = "Second number" }
},
required = new[] { "a", "b" }
},
(JsonElement? args) =>
{
double a = args?.TryGetProperty("a", out JsonElement aEl) == true ? aEl.GetDouble() : 0;
double b = args?.TryGetProperty("b", out JsonElement bEl) == true ? bEl.GetDouble() : 0;
return (object)(a + b);
});
// Start the server
await server.StartAsync();
Console.WriteLine("MCP HTTP server running on http://localhost:8080");
await Task.Delay(Timeout.Infinite, server.TokenSource.Token);默认值 McpHttpServer 监听所有三个HTTP端点:
/rpc用于请求/响应JSON-RPC/events用于经典的SSE通知/mcp适用于MCP流式HTTP
集 mcpPath: null 如果要禁用Streamable HTTP端点,请在构造函数中执行。
快速入门:MCP客户端(HTTP)
using Voltaic;
McpHttpClient client = new McpHttpClient();
// Connect to the HTTP server
await client.ConnectAsync("http://localhost:8080");
// Start SSE connection for server notifications
await client.StartSseAsync();
// Call methods on the server
object? result = await client.CallAsync("tools/list");
Console.WriteLine(result);快速入门:MCP客户端(流式HTTP)
using Voltaic;
McpHttpClient client = new McpHttpClient();
// Establish the RPC/session side on POST /mcp
await client.ConnectStreamableAsync("http://localhost:8080");
// Open the SSE side on GET /mcp for notifications
await client.StartSseAsync();
// Call methods on the same session
object? result = await client.CallAsync("tools/list");
Console.WriteLine(result);ConnectStreamableAsync() 建立会话和POST端点。呼叫 StartSseAsync() 当您希望SSE通知流在同一设备上处于活动状态时 /mcp 终点。
快速入门:MCP服务器(WebSocket)
using System.Text.Json;
using Voltaic;
McpWebsocketsServer server = new McpWebsocketsServer("localhost", 8080);
// Subscribe to events
server.ClientConnected += (sender, client) =>
Console.WriteLine($"WebSocket client connected: {client.SessionId}");
server.ResponseSent += (sender, e) =>
Console.WriteLine($"Sent response for {e.Method} in {e.Duration.TotalMilliseconds}ms");
// Register a method (tools/call dispatches to registered methods by name)
server.RegisterMethod("add", (JsonElement? args) =>
{
double a = args?.TryGetProperty("a", out JsonElement aEl) == true ? aEl.GetDouble() : 0;
double b = args?.TryGetProperty("b", out JsonElement bEl) == true ? bEl.GetDouble() : 0;
return (object)(a + b);
});
// Register tools/list so clients can discover available tools
server.RegisterMethod("tools/list", (JsonElement? args) =>
{
return new
{
tools = new[]
{
new
{
name = "add",
description = "Adds two numbers",
inputSchema = new
{
type = "object",
properties = new
{
a = new { type = "number", description = "First number" },
b = new { type = "number", description = "Second number" }
},
required = new[] { "a", "b" }
}
}
}
};
});
// Start the server
await server.StartAsync();
Console.WriteLine("MCP WebSocket server running on ws://localhost:8080");
await Task.Delay(Timeout.Infinite, server.TokenSource.Token);快速入门:MCP客户端(WebSocket)
using Voltaic;
McpWebsocketsClient client = new McpWebsocketsClient();
// Subscribe to server notifications
client.NotificationReceived += (sender, request) =>
Console.WriteLine($"Server notification: {request.Method}");
// Connect to the WebSocket server
await client.ConnectAsync("ws://localhost:8080/mcp");
// Call methods on the server
object? result = await client.CallAsync("tools/list");
Console.WriteLine(result);
// Send a notification
await client.NotifyAsync("log", new { message = "Hello from WebSocket client" });______________________________________________________________________
什么时候不使用这个
如果您需要,Voltaic可能不是合适的选择:
- gRPC功能:如果您需要流媒体、高级负载平衡或语言无关的服务定义,请使用gRPC
- REST约定:如果您需要具有标准HTTP谓词的面向资源的API,请使用web API或REST微服务
- 高级抽象Voltaic是一个协议库,而不是一个框架——你将编写自己的业务逻辑
______________________________________________________________________
资源管理
所有服务器和客户端类都实现 IDisposable 使用完整的“处理”模式(protected virtual void Dispose(bool disposing))具有双重处置保护。使用 using 声明或电话 Dispose() 为了确保适当的资源清理:
// Recommended: using statement ensures cleanup
using McpHttpServer server = new McpHttpServer("localhost", 8080);
await server.StartAsync();
// Or manually dispose
McpHttpServer server2 = new McpHttpServer("localhost", 8081);
try
{
await server2.StartAsync();
}
finally
{
server2.Dispose();
}要点:
Dispose()多次调用是安全的——后续调用没有操作- 对于服务器,
Dispose()电话Stop()在内部,断开所有客户端并释放侦听端口 - 对于客户来说,
Dispose()电话Disconnect()在内部,取消待处理的请求 Disconnect()/Stop()仅管理连接状态--Dispose()释放底层资源(套接字、侦听器、取消令牌)- 所有课程均支持
protected virtual void Dispose(bool disposing)子类可扩展性模式
______________________________________________________________________
文档
所有类和方法都可以在 Voltaic 命名空间。
JSON-RPC服务器和客户端
服务器API(JsonRpcServer):
*施工单位:*
JsonRpcServer(IPAddress ip, int port, bool includeDefaultMethods = true)-创建一个在指定IP地址和端口上侦听的服务器
*方法:*
void RegisterMethod(string name, Func handler)-注册同步RPC方法void RegisterMethod(string name, Func> handler)-注册异步RPC方法void RegisterMethod(string name, Func> handler)-注册一个支持取消的异步RPC方法Task StartAsync(CancellationToken token = default)-开始接受连接Task BroadcastNotificationAsync(string method, object? parameters, CancellationToken token = default)-向所有客户端发送通知List GetConnectedClients()-获取已连接客户端ID的列表bool KickClient(string clientId)-按ID断开特定客户端的连接void Stop()-优雅地关闭服务器void Dispose()-释放所有资源(内部调用Stop(),可以多次安全调用)
*属性:*
int MaxQueueSize { get; set; }-每个客户端的最大排队通知数(默认值:100,最小值:1)CancellationTokenSource? TokenSource { get; }-服务器的取消令牌源string DefaultContentType { get; set; }-消息的Content-Type标头(默认值:“application/json;字符集=utf-8”)
*活动:*
event EventHandler ClientConnected-客户端连接时发生火灾event EventHandler ClientDisconnected-当客户端断开连接时触发event EventHandler RequestReceived-收到请求时触发event EventHandler ResponseSent-发送响应时发生火灾event EventHandler Log-生成日志消息时发生火灾
客户端API(JsonRpcClient):
*方法:*
Task ConnectAsync(string host, int port, CancellationToken token = default)-连接到服务器Task CallAsync(string method, object? parameters = null, int timeoutMs = 30000, CancellationToken token = default)-发出RPC调用并等待键入的响应Task CallAsync(string method, object? parameters = null, int timeoutMs = 30000, CancellationToken token = default)-发出RPC调用并等待响应Task NotifyAsync(string method, object? parameters = null, CancellationToken token = default)-发送通知(无响应)void Disconnect()-关闭连接void Dispose()-释放所有资源(内部调用Disconnect(),可以多次安全调用)
*属性:*
bool IsConnected { get; }-客户端当前是否已连接TcpClient? TcpClient { get; }-底层TCP客户端CancellationTokenSource? TokenSource { get; }-取消令牌来源string DefaultContentType { get; set; }-消息的Content-Type标头
*活动:*
event EventHandler NotificationReceived-从服务器收到通知时触发event EventHandler Log-生成日志消息时发生火灾
MCP服务器和客户端
McpServer(stdio):
*方法:*
void RegisterMethod(string name, Func handler)-注册同步MCP方法void RegisterMethod(string name, Func> handler)-注册异步MCP方法void RegisterMethod(string name, Func> handler)-注册支持取消的异步MCP方法void RegisterTool(string name, string description, object inputSchema, Func handler)-使用同步处理程序注册工具void RegisterTool(string name, string description, object inputSchema, Func> handler)-使用异步处理程序注册工具void RegisterTool(string name, string description, object inputSchema, Func> handler)-使用异步可取消处理程序注册工具Task RunAsync(CancellationToken token = default)-运行服务器(阻塞,直到stdin关闭)void Dispose()-释放所有资源(可以多次安全调用)
*属性:*
string ProtocolVersion { get; set; }-MCP协议版本(默认:“2025-03-26”)string ServerName { get; set; }-MCP服务器信息的服务器名称(默认:“Voltaic.MCP.StdioServer”)string ServerVersion { get; set; }-MCP服务器信息的服务器版本(默认:“1.0.0”)
*内置方法:*
initialize-MCP协议初始化(返回功能和服务器信息)tools/list-列出已注册的工具tools/call-按名称调用工具notifications/initialized-处理客户端初始化通知ping,echo,getTime-实用工具
*活动:*
event EventHandler Log-生成日志消息时发生火灾
MCPClient(stdio):
*方法:*
Task LaunchServerAsync(string executable, string[] args, CancellationToken token = default)-启动子流程服务器Task CallAsync(string method, object? parameters = null, int timeoutMs = 30000, CancellationToken token = default)-使用类型化响应调用服务器方法Task CallAsync(string method, object? parameters = null, int timeoutMs = 30000, CancellationToken token = default)-呼叫服务器方法Task NotifyAsync(string method, object? parameters = null, CancellationToken token = default)-发送通知void StopServer()-停止子流程服务器void Dispose()-释放所有资源(内部调用Shutdown(),可以多次安全调用)
*活动:*
event EventHandler NotificationReceived-处理服务器通知event EventHandler Log-生成日志消息时发生火灾
McpTcpServer(基于TCP的MCP):
继承自 JsonRpcServer 具有额外的MCP特定内置方法。所有JsonRpcServer API都适用,此外:
*其他内置方法:*
initialize-MCP协议初始化tools/list-列出已注册的工具tools/call-按名称调用工具
McpTcpClient(基于TCP的MCP):
*方法:*
- 同
JsonRpcClient Task ConnectAsync(string host, int port, CancellationToken token = default)-连接到TCP服务器Task CallAsync(string method, object? parameters = null, int timeoutMs = 30000, CancellationToken token = default)-键入响应的呼叫
McpHttpServer(基于HTTP的MCP,带SSE):
*施工单位:*
McpHttpServer(string hostname, int port, string rpcPath = "/rpc", string eventsPath = "/events", bool includeDefaultMethods = true, string? mcpPath = "/mcp")
*方法:*
void RegisterMethod(string name, Func handler)-注册同步RPC方法void RegisterMethod(string name, Func> handler)-注册异步RPC方法void RegisterMethod(string name, Func> handler)-注册一个支持取消的异步RPC方法void RegisterTool(string name, string description, object inputSchema, Func handler)-使用同步处理程序注册工具void RegisterTool(string name, string description, object inputSchema, Func> handler)-使用异步处理程序注册工具void RegisterTool(string name, string description, object inputSchema, Func> handler)-使用异步可取消处理程序注册工具Task StartAsync(CancellationToken token = default)-启动HTTP服务器bool SendNotificationToSession(string sessionId, string method, object? parameters = null)-向特定会话发送通知void BroadcastNotification(string method, object? parameters = null)-向所有会话广播List GetActiveSessions()-获取活动会话ID列表List GetConnectedClients()-获取已连接客户端ID的列表bool KickClient(string clientId)-断开特定客户端的连接bool RemoveSession(string sessionId)-删除会话void Stop()-停止服务器void Dispose()-释放所有资源(内部调用Stop(),可以多次安全调用)
*属性:*
Func>? AuthenticationHandler { get; set; }-可选异步身份验证处理程序。设置后,每个请求在处理前都会经过身份验证。当为null(默认)时,接受所有请求int SessionTimeoutSeconds { get; set; }-会话超时(默认值:300,分钟:10)int MaxQueueSize { get; set; }-每个客户端的最大排队通知数(默认值:100,最小值:1)bool EnableCors { get; set; }-启用CORS支持(默认值:true)Dictionary CorsHeaders { get; set; }-CORS标头配置string ProtocolVersion { get; set; }-MCP协议版本(默认:“2025-03-26”)string ServerName { get; set; }-MCP服务器的服务器名称信息string ServerVersion { get; set; }-MCP服务器的服务器版本信息
*活动:*
event EventHandler ClientConnected-创建会话时触发event EventHandler ClientDisconnected-删除会话时发生火灾event EventHandler RequestReceived-收到请求时触发event EventHandler ResponseSent-发送响应时发生火灾event EventHandler Log-生成日志消息时发生火灾
McpHttpClient(基于HTTP的MCP):
*方法:*
Task ConnectAsync(string baseUrl, CancellationToken token = default)-连接到HTTP服务器Task ConnectStreamableAsync(string baseUrl, string mcpPath = "/mcp", CancellationToken token = default)-在上建立流式HTTP会话/mcpTask StartSseAsync(CancellationToken token = default)-启动服务器发送通知事件/events或/mcpvoid StopSse()-停止SSE连接Task CallAsync(string method, object? parameters = null, int timeoutMs = 30000, CancellationToken token = default)-键入响应的呼叫Task CallAsync(string method, object? parameters = null, int timeoutMs = 30000, CancellationToken token = default)-调用方法Task NotifyAsync(string method, object? parameters = null, CancellationToken token = default)-发送通知void Disconnect()-断开与服务器的连接void Dispose()-释放所有资源(内部调用Disconnect(),可以多次安全调用)
*属性:*
string? SessionId { get; }-服务器分配的会话IDbool IsConnected { get; }-连接状态bool IsSseConnected { get; }-SSE连接状态
*活动:*
event EventHandler NotificationReceived-处理服务器通知event EventHandler Log-生成日志消息时发生火灾
McpWebsocketsServer(基于WebSocket的MCP):
*施工单位:*
McpWebsocketsServer(string hostname, int port, string path = "/mcp", bool includeDefaultMethods = true)
*方法:*
void RegisterMethod(string name, Func handler)-注册同步RPC方法void RegisterMethod(string name, Func> handler)-注册异步RPC方法void RegisterMethod(string name, Func> handler)-注册一个支持取消的异步RPC方法Task StartAsync(CancellationToken token = default)-启动WebSocket服务器Task BroadcastNotificationAsync(string method, object? parameters = null, CancellationToken token = default)-向所有客户广播List GetConnectedClients()-获取已连接客户端ID的列表bool KickClient(string clientId)-断开特定客户端的连接void Stop()-停止服务器void Dispose()-释放所有资源(内部调用Stop(),可以多次安全调用)
*属性:*
int MaxMessageSize { get; set; }-最大消息大小(以字节为单位)(默认值:1MB,最小值:4096)int KeepAliveIntervalSeconds { get; set; }-WebSocket保持活动间隔(默认值:30,0表示禁用)int MaxQueueSize { get; set; }-每个客户端的最大排队通知数(默认值:100,最小值:1)string ProtocolVersion { get; set; }-MCP协议版本string ServerName { get; set; }-MCP服务器的服务器名称信息string ServerVersion { get; set; }-MCP服务器的服务器版本信息
*活动:*
event EventHandler ClientConnected-客户端连接时发生火灾event EventHandler ClientDisconnected-当客户端断开连接时触发event EventHandler RequestReceived-收到请求时触发event EventHandler ResponseSent-发送响应时发生火灾event EventHandler Log-生成日志消息时发生火灾
McpWebsocketsClient(基于WebSocket的MCP):
*方法:*
Task ConnectAsync(string url, CancellationToken token = default)-连接到WebSocket服务器Task CallAsync(string method, object? parameters = null, int timeoutMs = 30000, CancellationToken token = default)-键入响应的呼叫Task CallAsync(string method, object? parameters = null, int timeoutMs = 30000, CancellationToken token = default)-调用方法Task NotifyAsync(string method, object? parameters = null, CancellationToken token = default)-发送通知void Disconnect()-关闭连接void Dispose()-释放所有资源(内部调用Disconnect(),可以多次安全调用)
*属性:*
bool IsConnected { get; }-连接状态int MaxMessageSize { get; set; }-最大邮件大小
*活动:*
event EventHandler NotificationReceived-处理服务器通知event EventHandler Log-生成日志消息时发生火灾
事件处理程序示例
所有服务器类型都支持用于监视连接生命周期和请求/响应活动的事件处理程序:
监控客户端连接:
using System.Net;
using Voltaic;
JsonRpcServer server = new JsonRpcServer(IPAddress.Any, 8080);
server.ClientConnected += (sender, client) =>
{
Console.WriteLine($"New client: {client.SessionId}");
Console.WriteLine($"Connection type: {client.Type}");
Console.WriteLine($"Connected at: {client.LastActivity:yyyy-MM-dd HH:mm:ss}");
};
server.ClientDisconnected += (sender, client) =>
{
Console.WriteLine($"Client {client.SessionId} disconnected");
Console.WriteLine($"Queued notifications: {client.Count()}");
};
await server.StartAsync();跟踪请求和响应:
using System.Net;
using Voltaic;
JsonRpcServer server = new JsonRpcServer(IPAddress.Any, 8080);
server.RequestReceived += (sender, e) =>
{
Console.WriteLine($"[{e.ReceivedUtc:HH:mm:ss.fff}] Request from {e.Client.SessionId}");
Console.WriteLine($" Method: {e.Method}");
Console.WriteLine($" Request ID: {e.RequestId}");
Console.WriteLine($" Is Notification: {e.IsNotification}");
};
server.ResponseSent += (sender, e) =>
{
string status = e.IsSuccess ? "✓" : "✗";
Console.WriteLine($"[{e.SentUtc:HH:mm:ss.fff}] {status} Response to {e.Client.SessionId}");
Console.WriteLine($" Method: {e.Method}");
Console.WriteLine($" Duration: {e.Duration.TotalMilliseconds:F2}ms");
Console.WriteLine($" Success: {e.IsSuccess}");
if (e.IsError)
{
Console.WriteLine($" Error: {e.Response.Error?.Message}");
}
};
await server.StartAsync();管理客户端队列:
using System.Net;
using Voltaic;
JsonRpcServer server = new JsonRpcServer(IPAddress.Any, 8080);
// Configure queue size
server.MaxQueueSize = 50; // Max 50 notifications per client
server.ClientConnected += (sender, client) =>
{
// Per-client queue configuration
client.MaxQueueSize = 100; // Override for this specific client
Console.WriteLine($"Client {client.SessionId} queue size: {client.MaxQueueSize}");
};
// Monitor queue activity
server.ResponseSent += (sender, e) =>
{
int queuedCount = e.Client.Count();
if (queuedCount > 40)
{
Console.WriteLine($"WARNING: Client {e.Client.SessionId} queue is {queuedCount}/50");
}
};
await server.StartAsync();构建请求度量:
using System.Collections.Concurrent;
using System.Net;
using Voltaic;
JsonRpcServer server = new JsonRpcServer(IPAddress.Any, 8080);
ConcurrentDictionary requestCounts = new();
ConcurrentDictionary> responseTimes = new();
server.RequestReceived += (sender, e) =>
{
requestCounts.AddOrUpdate(e.Method, 1, (key, count) => count + 1);
};
server.ResponseSent += (sender, e) =>
{
double ms = e.Duration.TotalMilliseconds;
responseTimes.AddOrUpdate(
e.Method,
new List { ms },
(key, list) => { list.Add(ms); return list; }
);
};
// Print stats every 10 seconds
Timer statsTimer = new Timer(_ =>
{
Console.WriteLine("\n=== Request Statistics ===");
foreach (var kvp in requestCounts.OrderByDescending(x => x.Value))
{
var times = responseTimes.GetValueOrDefault(kvp.Key, new List());
double avgMs = times.Count > 0 ? times.Average() : 0;
Console.WriteLine($"{kvp.Key}: {kvp.Value} requests, avg {avgMs:F2}ms");
}
}, null, TimeSpan.FromSeconds(10), TimeSpan.FromSeconds(10));
await server.StartAsync();处理客户端通知:
using Voltaic;
JsonRpcClient client = new JsonRpcClient();
client.NotificationReceived += (sender, request) =>
{
Console.WriteLine($"Server notification: {request.Method}");
// Handle specific notification types
switch (request.Method)
{
case "server/shutdown":
Console.WriteLine("Server is shutting down!");
break;
case "broadcast":
var message = request.Params?.ToString();
Console.WriteLine($"Broadcast: {message}");
break;
default:
Console.WriteLine($"Unknown notification: {request.Method}");
break;
}
};
await client.ConnectAsync("localhost", 8080);事件驱动客户端管理:
using System.Collections.Concurrent;
using Voltaic;
McpWebsocketsServer server = new McpWebsocketsServer("localhost", 8080);
ConcurrentDictionary activeClients = new();
server.ClientConnected += (sender, client) =>
{
activeClients[client.SessionId] = client;
// Send welcome notification to the new client
JsonRpcRequest welcome = new JsonRpcRequest
{
Method = "welcome",
Params = new { message = $"Welcome {client.SessionId}!" }
};
client.Enqueue(welcome);
};
server.ClientDisconnected += (sender, client) =>
{
activeClients.TryRemove(client.SessionId, out _);
// Notify other clients
foreach (var otherClient in activeClients.Values)
{
JsonRpcRequest notification = new JsonRpcRequest
{
Method = "client_left",
Params = new { clientId = client.SessionId }
};
otherClient.Enqueue(notification);
}
};
await server.StartAsync();______________________________________________________________________
示例
看看 src/Test.* 工作示例项目:
- 测试。JsonRpc服务器 / 测试。JsonRpcClient:基于TCP的交互式JSON-RPC演示
- 测试。McpServer / 测试。McpClient:MCP标准操作示例
- 测试。McpHttp服务器 / 测试。McpHttp客户端:MCP HTTP和SSE示例
- 测试。McpWebsocketsServer / 测试。McpWebsocketsClient:MCP WebSocket示例
- 测试。自动化:显示各种使用模式的综合测试套件
运行示例:
# JSON-RPC Server (TCP)
dotnet run --project src/Test.JsonRpcServer/Test.JsonRpcServer.csproj -- 8080
# JSON-RPC Client (TCP)
dotnet run --project src/Test.JsonRpcClient/Test.JsonRpcClient.csproj -- 8080
# MCP Stdio Client (launches server subprocess)
dotnet run --project src/Test.McpClient/Test.McpClient.csproj
# MCP HTTP Server
dotnet run --project src/Test.McpHttpServer/Test.McpHttpServer.csproj -- 8080
# MCP HTTP Client
dotnet run --project src/Test.McpHttpClient/Test.McpHttpClient.csproj -- 8080
# MCP WebSocket Server
dotnet run --project src/Test.McpWebsocketsServer/Test.McpWebsocketsServer.csproj -- 8080
# MCP WebSocket Client
dotnet run --project src/Test.McpWebsocketsClient/Test.McpWebsocketsClient.csproj -- 8080与MCP检查员联系
这 MCP检查员 是一个用于测试和调试MCP服务器的可视化工具。要将MCP检查器连接到Voltaic MCP HTTP服务器,请执行以下操作:
- 启动MCP HTTP服务器:
dotnet run --project src/Test.McpHttpServer/Test.McpHttpServer.csproj -- 8080- 打开MCP检查器 在您的网络浏览器中
- 配置连接:
- 传输类型:选择 Streamable HTTP - 统一资源定位符:输入 http://{hostname}:{port}/mcp - 例如: http://localhost:8080/mcp - 如果您指定了自定义 mcpPath 创建服务器时,使用它而不是 /mcp
- 点击连接
- 验证连接:检查员应显示已注册工具的列表,并允许您以交互方式调用它们
备注:MCP Inspector目前支持通过Streamable HTTP进行HTTP传输。对于其他传输方式(TCP、WebSocket、stdio),请使用相应的客户端实现或命令行工具。
______________________________________________________________________
建筑
# Build everything
dotnet build src/Voltaic.sln
# Build the library
dotnet build src/Voltaic/Voltaic.csproj
# Run automated tests (all transports)
dotnet run --project src/Test.Automated/Test.Automated.csproj --framework net8.0
# Run automated tests for specific transport
dotnet run --project src/Test.Automated/Test.Automated.csproj --framework net8.0 -- -stdio
dotnet run --project src/Test.Automated/Test.Automated.csproj --framework net8.0 -- -tcp
dotnet run --project src/Test.Automated/Test.Automated.csproj --framework net8.0 -- -http
dotnet run --project src/Test.Automated/Test.Automated.csproj --framework net8.0 -- -ws
# Run automated tests for multiple transports
dotnet run --project src/Test.Automated/Test.Automated.csproj --framework net8.0 -- -tcp -http -ws______________________________________________________________________
许可证
Voltaic在 MIT许可证。在您的项目中自由使用它,无论是商业还是其他方面。
______________________________________________________________________
支持
需要帮助或发现错误?
- 问题:报告错误或请求功能
- 讨论:在以下网址提问和分享想法
