Files
sharp-basic/test/NetServer.Test/Examples/ExampleProgram.cs
T
2025-12-30 09:17:25 +08:00

229 lines
9.5 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using Sharp.NetServer;
using NetServer.Test.Examples.Controllers;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.DependencyInjection;
namespace NetServer.Test.Examples;
/// <summary>
/// 完整的使用示例程序
/// 演示如何使用 Sharp.NetServer 框架构建 RESTful API
/// </summary>
public class ExampleProgram
{
public static void Main(string[] args)
{
Console.WriteLine("=============================================");
Console.WriteLine(" Sharp.NetServer 完整示例");
Console.WriteLine("=============================================");
Console.WriteLine();
Console.WriteLine("这个示例展示了一个完整的 RESTful API 服务器");
Console.WriteLine("包含用户管理、产品管理和认证功能");
Console.WriteLine();
// 创建服务器构建器
var builder = new HttpServerBuilder();
// 配置监听地址
var port = args.Length > 0 && int.TryParse(args[0], out var p) ? p : 5000;
builder.UseUrls($"http://localhost:{port}/");
// 添加控制器(从当前程序集)
builder.AddControllers(typeof(ExampleProgram).Assembly);
// 配置 CORS - 允许跨域访问
builder.UseCors(options =>
{
options.AllowAnyOrigin = true; // 生产环境应限制来源
options.AllowedMethods = new[] { "GET", "POST", "PUT", "DELETE", "PATCH", "OPTIONS" };
options.AllowedHeaders = new[] { "Content-Type", "Authorization", "X-Requested-With" };
options.AllowCredentials = false; // AllowAnyOrigin=true 时必须为 false
});
// 启用认证和授权
builder.UseAuthentication();
builder.UseAuthorization();
// 配置服务 - 注册认证提供者
builder.ConfigureServices(services =>
{
services
.AddSingleton<Sharp.NetServer.Abstractions.IAuthenticationProvider, SimpleAuthenticationProvider>();
});
// 启用限流 - 防止滥用
builder.UseRateLimit();
// 启用响应缓存 - 提高性能
builder.UseResponseCache();
// 配置日志
builder.ConfigureLogging(services =>
{
services.AddLogging(logging =>
{
logging.AddConsole();
logging.SetMinimumLevel(LogLevel.Information);
logging.AddFilter("Microsoft", LogLevel.Warning); // 减少 Microsoft 库的日志
});
});
// 添加自定义中间件 - 请求计时
builder.UseMiddleware(next => async context =>
{
var startTime = DateTime.UtcNow;
var path = context.Request.RawUrl;
await next(context);
var duration = (DateTime.UtcNow - startTime).TotalMilliseconds;
if (duration > 100) // 慢请求警告
{
Console.ForegroundColor = ConsoleColor.Yellow;
Console.WriteLine($"[SLOW] {path} took {duration:F2}ms");
Console.ResetColor();
}
});
// 构建服务器
var server = builder.Build();
Console.WriteLine("正在启动服务器...");
Console.WriteLine();
// 在后台启动服务器
var cts = new CancellationTokenSource();
_ = Task.Run(async () =>
{
try
{
await server.StartAsync(cts.Token);
}
catch (Exception ex)
{
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine($"服务器错误: {ex.Message}");
Console.ResetColor();
}
}, cts.Token);
// 等待服务器启动
Thread.Sleep(1000);
Console.ForegroundColor = ConsoleColor.Green;
Console.WriteLine("✓ 服务器启动成功!");
Console.ResetColor();
Console.WriteLine();
Console.WriteLine($"监听地址: http://localhost:{port}/");
Console.WriteLine();
PrintApiEndpoints(port);
PrintExampleRequests(port);
Console.WriteLine();
Console.ForegroundColor = ConsoleColor.Cyan;
Console.WriteLine("按任意键停止服务器...");
Console.ResetColor();
Console.ReadKey();
Console.WriteLine();
Console.WriteLine("正在停止服务器...");
cts.Cancel();
server.Stop();
Console.ForegroundColor = ConsoleColor.Green;
Console.WriteLine("✓ 服务器已停止");
Console.ResetColor();
}
private static void PrintApiEndpoints(int port)
{
Console.WriteLine("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━");
Console.WriteLine("可用的 API 端点:");
Console.WriteLine("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━");
Console.WriteLine();
Console.ForegroundColor = ConsoleColor.Yellow;
Console.WriteLine("【认证接口】");
Console.ResetColor();
Console.WriteLine($" POST http://localhost:{port}/api/auth/login");
Console.WriteLine($" POST http://localhost:{port}/api/auth/logout");
Console.WriteLine($" GET http://localhost:{port}/api/auth/me");
Console.WriteLine($" POST http://localhost:{port}/api/auth/change-password");
Console.WriteLine();
Console.ForegroundColor = ConsoleColor.Yellow;
Console.WriteLine("【用户管理】");
Console.ResetColor();
Console.WriteLine($" GET http://localhost:{port}/api/users");
Console.WriteLine($" GET http://localhost:{port}/api/users/{{id}}");
Console.WriteLine($" POST http://localhost:{port}/api/users");
Console.WriteLine($" PUT http://localhost:{port}/api/users/{{id}}");
Console.WriteLine($" DELETE http://localhost:{port}/api/users/{{id}}");
Console.WriteLine($" GET http://localhost:{port}/api/users/search?keyword=张");
Console.WriteLine();
Console.ForegroundColor = ConsoleColor.Yellow;
Console.WriteLine("【产品管理】");
Console.ResetColor();
Console.WriteLine($" GET http://localhost:{port}/api/products");
Console.WriteLine($" GET http://localhost:{port}/api/products/{{id}}");
Console.WriteLine($" POST http://localhost:{port}/api/products");
Console.WriteLine($" PATCH http://localhost:{port}/api/products/{{id}}/stock");
Console.WriteLine($" DELETE http://localhost:{port}/api/products/{{id}}");
Console.WriteLine($" GET http://localhost:{port}/api/products/search?q=键盘");
Console.WriteLine();
}
private static void PrintExampleRequests(int port)
{
Console.WriteLine("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━");
Console.WriteLine("示例请求(可以使用 curl 或 Postman 测试):");
Console.WriteLine("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━");
Console.WriteLine();
Console.ForegroundColor = ConsoleColor.Cyan;
Console.WriteLine("1. 用户登录(获取 Token):");
Console.ResetColor();
Console.WriteLine($" curl -X POST http://localhost:{port}/api/auth/login \\");
Console.WriteLine($" -H \"Content-Type: application/json\" \\");
Console.WriteLine($" -d '{{\"username\":\"admin\",\"password\":\"admin123\"}}'");
Console.WriteLine();
Console.ForegroundColor = ConsoleColor.Cyan;
Console.WriteLine("2. 获取所有产品(无需认证):");
Console.ResetColor();
Console.WriteLine($" curl http://localhost:{port}/api/products");
Console.WriteLine();
Console.ForegroundColor = ConsoleColor.Cyan;
Console.WriteLine("3. 搜索用户(无需认证):");
Console.ResetColor();
Console.WriteLine($" curl http://localhost:{port}/api/users/search?keyword=张");
Console.WriteLine();
Console.ForegroundColor = ConsoleColor.Cyan;
Console.WriteLine("4. 获取用户信息(需要认证):");
Console.ResetColor();
Console.WriteLine($" curl http://localhost:{port}/api/users/1 \\");
Console.WriteLine($" -H \"Authorization: Bearer YOUR_TOKEN\"");
Console.WriteLine();
Console.ForegroundColor = ConsoleColor.Cyan;
Console.WriteLine("5. 创建产品(需要 Admin 角色):");
Console.ResetColor();
Console.WriteLine($" curl -X POST http://localhost:{port}/api/products \\");
Console.WriteLine($" -H \"Content-Type: application/json\" \\");
Console.WriteLine($" -H \"Authorization: Bearer YOUR_TOKEN\" \\");
Console.WriteLine($" -d '{{\"name\":\"新产品\",\"price\":299,\"stock\":50,\"category\":\"测试\"}}'");
Console.WriteLine();
Console.ForegroundColor = ConsoleColor.Yellow;
Console.WriteLine("💡 提示:");
Console.ResetColor();
Console.WriteLine(" - 默认管理员账号: admin / admin123");
Console.WriteLine(" - 默认普通用户: user / user123");
Console.WriteLine(" - Token 有效期: 1小时");
Console.WriteLine(" - 某些接口有限流保护");
}
}