Skip to content

FBro内置服务器

概述

FBro提供了内置的HTTP/WebSocket服务器功能,支持静态文件服务、RESTful API、WebSocket通信等。该服务器可以用于本地应用开发、测试环境搭建、轻量级Web服务等场景。

核心概念

服务器功能特性

  • HTTP服务器:支持静态文件服务和动态HTTP请求处理
  • WebSocket支持:提供实时双向通信能力
  • 多连接管理:支持并发连接和连接状态管理
  • 自定义回调:灵活的事件处理机制
  • 文件类型识别:自动识别文件类型并设置正确的Content-Type

关键组件

  • FBroSharpServer:服务器主类
  • FBroSharpServerHandle:服务器事件处理基类
  • IFBroSharpRequest:HTTP请求接口
  • IFBroSharpCallback:回调接口

基础配置

1. 创建基础服务器

csharp
/// <summary>
/// 创建基础HTTP服务器
/// </summary>
/// <param name="host">服务器地址</param>
/// <param name="port">端口号</param>
/// <param name="maxConnections">最大连接数</param>
/// <returns>是否创建成功</returns>
public bool CreateBasicServer(string host = "127.0.0.1", int port = 7777, int maxConnections = 100)
{
    try
    {
        // 创建服务器回调处理器
        var serverCallback = new FBroSharpServerHandleDis();
        
        // 创建服务器实例
        var server = FBroSharpServer.CreateServer(host, port, maxConnections, serverCallback);
        
        if (server != null)
        {
            Console.WriteLine($"服务器创建成功: {host}:{port}");
            Console.WriteLine($"最大连接数: {maxConnections}");
            return true;
        }
        else
        {
            Console.WriteLine("服务器创建失败");
            return false;
        }
    }
    catch (Exception ex)
    {
        Console.WriteLine($"创建服务器异常: {ex.Message}");
        return false;
    }
}

2. 高级服务器配置

csharp
/// <summary>
/// 服务器配置类
/// </summary>
public class FBroServerConfig
{
    public string Host { get; set; } = "127.0.0.1";
    public int Port { get; set; } = 7777;
    public int MaxConnections { get; set; } = 100;
    public string StaticFileRoot { get; set; } = "dist";
    public string DefaultFile { get; set; } = "index.html";
    public bool EnableWebSocket { get; set; } = true;
    public bool EnableCORS { get; set; } = true;
    public Dictionary<string, string> CustomHeaders { get; set; } = new Dictionary<string, string>();
}

/// <summary>
/// 创建高级配置服务器
/// </summary>
/// <param name="config">服务器配置</param>
/// <returns>服务器实例</returns>
public IFBroSharpServer CreateAdvancedServer(FBroServerConfig config)
{
    try
    {
        // 验证配置
        ValidateServerConfig(config);
        
        // 创建高级服务器回调处理器
        var serverCallback = new AdvancedServerHandler(config);
        
        // 创建服务器
        var server = FBroSharpServer.CreateServer(config.Host, config.Port, config.MaxConnections, serverCallback);
        
        if (server != null)
        {
            Console.WriteLine($"高级服务器创建成功: {config.Host}:{config.Port}");
            Console.WriteLine($"静态文件根目录: {config.StaticFileRoot}");
            Console.WriteLine($"WebSocket支持: {(config.EnableWebSocket ? "启用" : "禁用")}");
        }
        
        return server;
    }
    catch (Exception ex)
    {
        Console.WriteLine($"创建高级服务器失败: {ex.Message}");
        throw;
    }
}

/// <summary>
/// 验证服务器配置
/// </summary>
/// <param name="config">服务器配置</param>
private void ValidateServerConfig(FBroServerConfig config)
{
    if (string.IsNullOrEmpty(config.Host))
        throw new ArgumentException("服务器地址不能为空");
        
    if (config.Port <= 0 || config.Port > 65535)
        throw new ArgumentException("端口号必须在1-65535之间");
        
    if (config.MaxConnections <= 0)
        throw new ArgumentException("最大连接数必须大于0");
        
    if (!string.IsNullOrEmpty(config.StaticFileRoot) && !Directory.Exists(config.StaticFileRoot))
    {
        Directory.CreateDirectory(config.StaticFileRoot);
        Console.WriteLine($"创建静态文件目录: {config.StaticFileRoot}");
    }
}

服务器事件处理

基础服务器回调实现

csharp
/// <summary>
/// 基础服务器事件处理器
/// </summary>
public class FBroSharpServerHandleDis : FBroSharpServerHandle
{
    private const string LogFormat = "方法:{0} 地址:{1}";

    /// <summary>
    /// 客户端连接事件
    /// </summary>
    /// <param name="server">服务器实例</param>
    /// <param name="connection_id">连接ID</param>
    public override void OnClientConnected(IFBroSharpServer server, int connection_id)
    {
        Console.WriteLine(string.Format(LogFormat, MethodBase.GetCurrentMethod().Name, server.GetAddress()));
        Console.WriteLine($"客户端连接: ID={connection_id}");
    }

    /// <summary>
    /// 客户端断开连接事件
    /// </summary>
    /// <param name="server">服务器实例</param>
    /// <param name="connection_id">连接ID</param>
    public override void OnClientDisconnected(IFBroSharpServer server, int connection_id)
    {
        Console.WriteLine(string.Format(LogFormat, MethodBase.GetCurrentMethod().Name, server.GetAddress()));
        Console.WriteLine($"客户端断开: ID={connection_id}");
    }

    /// <summary>
    /// HTTP请求处理
    /// </summary>
    /// <param name="server">服务器实例</param>
    /// <param name="connection_id">连接ID</param>
    /// <param name="client_address">客户端地址</param>
    /// <param name="request">HTTP请求对象</param>
    public override void OnHttpRequest(IFBroSharpServer server, int connection_id, string client_address, IFBroSharpRequest request)
    {
        Console.WriteLine(string.Format(LogFormat, MethodBase.GetCurrentMethod().Name, server.GetAddress()));
        Console.WriteLine($"请求地址: {request.GetURL()}");
        Console.WriteLine($"客户端: {client_address}");

        try
        {
            ProcessHttpRequest(server, connection_id, request);
        }
        catch (Exception ex)
        {
            Console.WriteLine($"处理HTTP请求异常: {ex.Message}");
            SendErrorResponse(server, connection_id, 500, "Internal Server Error");
        }
    }

    /// <summary>
    /// 服务器创建事件
    /// </summary>
    /// <param name="server">服务器实例</param>
    public override void OnServerCreated(IFBroSharpServer server)
    {
        Console.WriteLine(string.Format(LogFormat, MethodBase.GetCurrentMethod().Name, server.GetAddress()));
        Console.WriteLine("服务器启动完成");
    }

    /// <summary>
    /// 服务器销毁事件
    /// </summary>
    /// <param name="server">服务器实例</param>
    public override void OnServerDestroyed(IFBroSharpServer server)
    {
        Console.WriteLine(string.Format(LogFormat, MethodBase.GetCurrentMethod().Name, server.GetAddress()));
        Console.WriteLine("服务器已关闭");
    }

    /// <summary>
    /// WebSocket连接事件
    /// </summary>
    /// <param name="server">服务器实例</param>
    /// <param name="connection_id">连接ID</param>
    public override void OnWebSocketConnected(IFBroSharpServer server, int connection_id)
    {
        Console.WriteLine(string.Format(LogFormat, MethodBase.GetCurrentMethod().Name, server.GetAddress()));
        Console.WriteLine($"WebSocket连接: ID={connection_id}");
    }

    /// <summary>
    /// WebSocket消息处理
    /// </summary>
    /// <param name="server">服务器实例</param>
    /// <param name="connection_id">连接ID</param>
    /// <param name="data">消息数据</param>
    public override void OnWebSocketMessage(IFBroSharpServer server, int connection_id, byte[] data)
    {
        Console.WriteLine(string.Format(LogFormat, MethodBase.GetCurrentMethod().Name, server.GetAddress()));
        Console.WriteLine($"收到WebSocket消息: 长度={data.Length}");
        
        // 回显消息
        server.SendWebSocketMessage(connection_id, data);
    }

    /// <summary>
    /// WebSocket请求处理
    /// </summary>
    /// <param name="server">服务器实例</param>
    /// <param name="connection_id">连接ID</param>
    /// <param name="client_address">客户端地址</param>
    /// <param name="request">请求对象</param>
    /// <param name="callback">回调对象</param>
    public override void OnWebSocketRequest(IFBroSharpServer server, int connection_id, string client_address, IFBroSharpRequest request, IFBroSharpCallback callback)
    {
        Console.WriteLine(string.Format(LogFormat, MethodBase.GetCurrentMethod().Name, server.GetAddress()));
        Console.WriteLine($"WebSocket请求: {request.GetURL()}");
    }

    /// <summary>
    /// 处理HTTP请求
    /// </summary>
    /// <param name="server">服务器实例</param>
    /// <param name="connection_id">连接ID</param>
    /// <param name="request">请求对象</param>
    protected virtual void ProcessHttpRequest(IFBroSharpServer server, int connection_id, IFBroSharpRequest request)
    {
        string urlPath = new Uri(request.GetURL()).PathAndQuery;

        // 如果请求的路径是根路径,默认返回index.html
        if (urlPath == "/")
        {
            urlPath = "/index.html";
        }

        // 构建文件路径
        string applicationPath = Application.StartupPath;
        string filePath = Path.Combine(applicationPath, "dist", urlPath.TrimStart('/'));

        // 处理静态文件请求
        if (File.Exists(filePath))
        {
            ServeStaticFile(server, connection_id, filePath);
        }
        else
        {
            SendErrorResponse(server, connection_id, 404, "Not Found");
        }
    }

    /// <summary>
    /// 提供静态文件服务
    /// </summary>
    /// <param name="server">服务器实例</param>
    /// <param name="connection_id">连接ID</param>
    /// <param name="filePath">文件路径</param>
    protected void ServeStaticFile(IFBroSharpServer server, int connection_id, string filePath)
    {
        string contentType = GetContentType(Path.GetExtension(filePath));
        byte[] data = File.ReadAllBytes(filePath);
        
        server.SendHttp200Response(connection_id, contentType, data);
        Console.WriteLine($"发送文件: {Path.GetFileName(filePath)} ({data.Length} 字节)");
    }

    /// <summary>
    /// 发送错误响应
    /// </summary>
    /// <param name="server">服务器实例</param>
    /// <param name="connection_id">连接ID</param>
    /// <param name="statusCode">状态码</param>
    /// <param name="message">错误消息</param>
    protected void SendErrorResponse(IFBroSharpServer server, int connection_id, int statusCode, string message)
    {
        string responseHtml = $"<html><body><h1>{statusCode} {message}</h1></body></html>";
        
        switch (statusCode)
        {
            case 404:
                server.SendHttp404Response(connection_id);
                break;
            case 500:
                server.SendHttp500Response(connection_id, responseHtml);
                break;
            default:
                byte[] data = Encoding.UTF8.GetBytes(responseHtml);
                server.SendHttp200Response(connection_id, "text/html", data);
                break;
        }
    }

    /// <summary>
    /// 获取文件类型
    /// </summary>
    /// <param name="extension">文件扩展名</param>
    /// <returns>Content-Type</returns>
    protected string GetContentType(string extension)
    {
        return extension.ToLower() switch
        {
            ".html" => "text/html",
            ".css" => "text/css",
            ".js" => "application/javascript",
            ".json" => "application/json",
            ".png" => "image/png",
            ".jpg" or ".jpeg" => "image/jpeg",
            ".gif" => "image/gif",
            ".svg" => "image/svg+xml",
            ".ico" => "image/x-icon",
            ".txt" => "text/plain",
            ".xml" => "text/xml",
            ".pdf" => "application/pdf",
            _ => "application/octet-stream"
        };
    }
}

高级服务器回调实现

csharp
/// <summary>
/// 高级服务器事件处理器
/// </summary>
public class AdvancedServerHandler : FBroSharpServerHandleDis
{
    private readonly FBroServerConfig _config;
    private readonly Dictionary<int, ClientInfo> _clients = new Dictionary<int, ClientInfo>();
    private readonly Dictionary<string, Func<IFBroSharpRequest, object>> _apiRoutes = new Dictionary<string, Func<IFBroSharpRequest, object>>();

    public AdvancedServerHandler(FBroServerConfig config)
    {
        _config = config;
        InitializeApiRoutes();
    }

    /// <summary>
    /// 客户端连接时记录客户端信息
    /// </summary>
    public override void OnClientConnected(IFBroSharpServer server, int connection_id)
    {
        base.OnClientConnected(server, connection_id);
        
        _clients[connection_id] = new ClientInfo
        {
            ConnectionId = connection_id,
            ConnectedTime = DateTime.Now,
            IsWebSocket = false
        };
    }

    /// <summary>
    /// 客户端断开时清理信息
    /// </summary>
    public override void OnClientDisconnected(IFBroSharpServer server, int connection_id)
    {
        base.OnClientDisconnected(server, connection_id);
        _clients.Remove(connection_id);
    }

    /// <summary>
    /// WebSocket连接时更新客户端信息
    /// </summary>
    public override void OnWebSocketConnected(IFBroSharpServer server, int connection_id)
    {
        base.OnWebSocketConnected(server, connection_id);
        
        if (_clients.ContainsKey(connection_id))
        {
            _clients[connection_id].IsWebSocket = true;
        }
    }

    /// <summary>
    /// 高级HTTP请求处理
    /// </summary>
    protected override void ProcessHttpRequest(IFBroSharpServer server, int connection_id, IFBroSharpRequest request)
    {
        string urlPath = new Uri(request.GetURL()).PathAndQuery;
        string method = request.GetMethod();

        Console.WriteLine($"处理请求: {method} {urlPath}");

        // 添加CORS头
        if (_config.EnableCORS)
        {
            AddCORSHeaders(server, connection_id);
        }

        // 处理API路由
        if (urlPath.StartsWith("/api/"))
        {
            ProcessApiRequest(server, connection_id, request, urlPath);
            return;
        }

        // 处理静态文件
        ProcessStaticFileRequest(server, connection_id, urlPath);
    }

    /// <summary>
    /// 处理API请求
    /// </summary>
    private void ProcessApiRequest(IFBroSharpServer server, int connection_id, IFBroSharpRequest request, string urlPath)
    {
        try
        {
            if (_apiRoutes.TryGetValue(urlPath, out var handler))
            {
                var result = handler(request);
                string jsonResponse = JsonConvert.SerializeObject(result);
                byte[] data = Encoding.UTF8.GetBytes(jsonResponse);
                
                server.SendHttp200Response(connection_id, "application/json", data);
            }
            else
            {
                SendErrorResponse(server, connection_id, 404, "API Not Found");
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine($"API请求处理异常: {ex.Message}");
            var errorResponse = new { error = "Internal Server Error", message = ex.Message };
            string jsonResponse = JsonConvert.SerializeObject(errorResponse);
            byte[] data = Encoding.UTF8.GetBytes(jsonResponse);
            
            server.SendHttp500Response(connection_id, jsonResponse);
        }
    }

    /// <summary>
    /// 处理静态文件请求
    /// </summary>
    private void ProcessStaticFileRequest(IFBroSharpServer server, int connection_id, string urlPath)
    {
        // 如果是根路径,返回默认文件
        if (urlPath == "/")
        {
            urlPath = "/" + _config.DefaultFile;
        }

        // 构建文件路径
        string filePath = Path.Combine(_config.StaticFileRoot, urlPath.TrimStart('/'));
        
        // 安全检查:防止路径遍历攻击
        string fullPath = Path.GetFullPath(filePath);
        string rootPath = Path.GetFullPath(_config.StaticFileRoot);
        
        if (!fullPath.StartsWith(rootPath))
        {
            SendErrorResponse(server, connection_id, 403, "Forbidden");
            return;
        }

        if (File.Exists(fullPath))
        {
            ServeStaticFile(server, connection_id, fullPath);
        }
        else
        {
            SendErrorResponse(server, connection_id, 404, "Not Found");
        }
    }

    /// <summary>
    /// 添加CORS头
    /// </summary>
    private void AddCORSHeaders(IFBroSharpServer server, int connection_id)
    {
        // 注意:FBro可能不直接支持自定义响应头,这里是示例代码
        // 实际使用时需要根据FBro的API进行调整
    }

    /// <summary>
    /// 初始化API路由
    /// </summary>
    private void InitializeApiRoutes()
    {
        // 获取服务器状态
        _apiRoutes["/api/status"] = (request) =>
        {
            return new
            {
                status = "running",
                connections = _clients.Count,
                uptime = DateTime.Now.ToString(),
                version = "1.0.0"
            };
        };

        // 获取连接的客户端列表
        _apiRoutes["/api/clients"] = (request) =>
        {
            return _clients.Values.Select(c => new
            {
                connectionId = c.ConnectionId,
                connectedTime = c.ConnectedTime,
                isWebSocket = c.IsWebSocket,
                duration = DateTime.Now - c.ConnectedTime
            });
        };

        // 发送WebSocket消息到所有客户端
        _apiRoutes["/api/broadcast"] = (request) =>
        {
            // 这里需要实现广播逻辑
            return new { message = "Broadcast sent" };
        };
    }

    /// <summary>
    /// 获取当前连接的客户端数量
    /// </summary>
    public int GetConnectedClientsCount()
    {
        return _clients.Count;
    }

    /// <summary>
    /// 获取WebSocket客户端数量
    /// </summary>
    public int GetWebSocketClientsCount()
    {
        return _clients.Values.Count(c => c.IsWebSocket);
    }
}

/// <summary>
/// 客户端信息类
/// </summary>
public class ClientInfo
{
    public int ConnectionId { get; set; }
    public DateTime ConnectedTime { get; set; }
    public bool IsWebSocket { get; set; }
    public string UserAgent { get; set; }
    public string IPAddress { get; set; }
}

实际应用示例

1. 静态网站服务器

csharp
public class StaticWebServer
{
    private IFBroSharpServer _server;
    private readonly FBroServerConfig _config;

    public StaticWebServer(string webRoot, int port = 8080)
    {
        _config = new FBroServerConfig
        {
            Host = "0.0.0.0",
            Port = port,
            StaticFileRoot = webRoot,
            DefaultFile = "index.html",
            EnableCORS = true,
            MaxConnections = 200
        };
    }

    /// <summary>
    /// 启动静态网站服务器
    /// </summary>
    public bool Start()
    {
        try
        {
            var handler = new AdvancedServerHandler(_config);
            _server = FBroSharpServer.CreateServer(_config.Host, _config.Port, _config.MaxConnections, handler);
            
            if (_server != null)
            {
                Console.WriteLine($"静态网站服务器启动成功");
                Console.WriteLine($"访问地址: http://{_config.Host}:{_config.Port}");
                Console.WriteLine($"网站根目录: {Path.GetFullPath(_config.StaticFileRoot)}");
                return true;
            }
            
            return false;
        }
        catch (Exception ex)
        {
            Console.WriteLine($"启动静态网站服务器失败: {ex.Message}");
            return false;
        }
    }

    /// <summary>
    /// 停止服务器
    /// </summary>
    public void Stop()
    {
        _server?.Dispose();
        Console.WriteLine("静态网站服务器已停止");
    }
}

2. API服务器

csharp
public class ApiServer
{
    private IFBroSharpServer _server;
    private readonly Dictionary<string, object> _dataStore = new Dictionary<string, object>();

    /// <summary>
    /// 启动API服务器
    /// </summary>
    public bool StartApiServer(int port = 3000)
    {
        var config = new FBroServerConfig
        {
            Host = "127.0.0.1",
            Port = port,
            EnableCORS = true,
            MaxConnections = 50
        };

        var handler = new ApiServerHandler(_dataStore);
        _server = FBroSharpServer.CreateServer(config.Host, config.Port, config.MaxConnections, handler);

        if (_server != null)
        {
            Console.WriteLine($"API服务器启动成功: http://{config.Host}:{config.Port}");
            PrintApiEndpoints();
            return true;
        }

        return false;
    }

    /// <summary>
    /// 打印API端点
    /// </summary>
    private void PrintApiEndpoints()
    {
        Console.WriteLine("可用的API端点:");
        Console.WriteLine("  GET  /api/data/{key}    - 获取数据");
        Console.WriteLine("  POST /api/data/{key}    - 设置数据");
        Console.WriteLine("  GET  /api/data          - 获取所有数据");
        Console.WriteLine("  DELETE /api/data/{key}  - 删除数据");
    }
}

/// <summary>
/// API服务器处理器
/// </summary>
public class ApiServerHandler : FBroSharpServerHandleDis
{
    private readonly Dictionary<string, object> _dataStore;

    public ApiServerHandler(Dictionary<string, object> dataStore)
    {
        _dataStore = dataStore;
    }

    protected override void ProcessHttpRequest(IFBroSharpServer server, int connection_id, IFBroSharpRequest request)
    {
        string url = request.GetURL();
        string method = request.GetMethod();
        
        if (url.StartsWith("/api/"))
        {
            ProcessApiCall(server, connection_id, request, method, url);
        }
        else
        {
            // 返回API文档
            string apiDoc = GenerateApiDocumentation();
            byte[] data = Encoding.UTF8.GetBytes(apiDoc);
            server.SendHttp200Response(connection_id, "text/html", data);
        }
    }

    /// <summary>
    /// 处理API调用
    /// </summary>
    private void ProcessApiCall(IFBroSharpServer server, int connection_id, IFBroSharpRequest request, string method, string url)
    {
        try
        {
            object result = null;
            
            if (url.StartsWith("/api/data"))
            {
                result = HandleDataApi(method, url, request);
            }
            
            string jsonResponse = JsonConvert.SerializeObject(new { success = true, data = result });
            byte[] data = Encoding.UTF8.GetBytes(jsonResponse);
            server.SendHttp200Response(connection_id, "application/json", data);
        }
        catch (Exception ex)
        {
            var errorResponse = new { success = false, error = ex.Message };
            string jsonResponse = JsonConvert.SerializeObject(errorResponse);
            byte[] data = Encoding.UTF8.GetBytes(jsonResponse);
            server.SendHttp500Response(connection_id, jsonResponse);
        }
    }

    /// <summary>
    /// 处理数据API
    /// </summary>
    private object HandleDataApi(string method, string url, IFBroSharpRequest request)
    {
        var parts = url.Split('/');
        
        switch (method.ToUpper())
        {
            case "GET":
                if (parts.Length > 3)
                {
                    string key = parts[3];
                    return _dataStore.TryGetValue(key, out var value) ? value : null;
                }
                else
                {
                    return _dataStore;
                }
                
            case "POST":
                if (parts.Length > 3)
                {
                    string key = parts[3];
                    // 这里需要从请求体中获取数据
                    // 简化示例,使用当前时间作为值
                    _dataStore[key] = DateTime.Now.ToString();
                    return new { message = "Data saved", key = key };
                }
                break;
                
            case "DELETE":
                if (parts.Length > 3)
                {
                    string key = parts[3];
                    bool removed = _dataStore.Remove(key);
                    return new { message = removed ? "Data deleted" : "Key not found", key = key };
                }
                break;
        }
        
        throw new NotSupportedException($"不支持的操作: {method} {url}");
    }

    /// <summary>
    /// 生成API文档
    /// </summary>
    private string GenerateApiDocumentation()
    {
        return @"
<!DOCTYPE html>
<html>
<head>
    <title>API 文档</title>
    <style>
        body { font-family: Arial, sans-serif; margin: 40px; }
        .endpoint { margin: 20px 0; padding: 15px; border-left: 4px solid #007cba; background: #f8f9fa; }
        .method { font-weight: bold; color: #007cba; }
    </style>
</head>
<body>
    <h1>FBro API 服务器</h1>
    <div class='endpoint'>
        <div class='method'>GET /api/data</div>
        <div>获取所有存储的数据</div>
    </div>
    <div class='endpoint'>
        <div class='method'>GET /api/data/{key}</div>
        <div>获取指定键的数据</div>
    </div>
    <div class='endpoint'>
        <div class='method'>POST /api/data/{key}</div>
        <div>设置指定键的数据</div>
    </div>
    <div class='endpoint'>
        <div class='method'>DELETE /api/data/{key}</div>
        <div>删除指定键的数据</div>
    </div>
</body>
</html>";
    }
}

服务器管理器

ServerManager 统一管理类

csharp
/// <summary>
/// 服务器管理器
/// </summary>
public class ServerManager
{
    private readonly Dictionary<string, IFBroSharpServer> _servers = new Dictionary<string, IFBroSharpServer>();
    private readonly Dictionary<string, FBroServerConfig> _configs = new Dictionary<string, FBroServerConfig>();

    /// <summary>
    /// 创建并启动服务器
    /// </summary>
    /// <param name="serverId">服务器ID</param>
    /// <param name="config">服务器配置</param>
    /// <returns>是否成功</returns>
    public bool CreateServer(string serverId, FBroServerConfig config)
    {
        if (_servers.ContainsKey(serverId))
        {
            Console.WriteLine($"服务器 {serverId} 已存在");
            return false;
        }

        try
        {
            var handler = new AdvancedServerHandler(config);
            var server = FBroSharpServer.CreateServer(config.Host, config.Port, config.MaxConnections, handler);

            if (server != null)
            {
                _servers[serverId] = server;
                _configs[serverId] = config;
                
                Console.WriteLine($"服务器 {serverId} 创建成功: {config.Host}:{config.Port}");
                return true;
            }

            return false;
        }
        catch (Exception ex)
        {
            Console.WriteLine($"创建服务器 {serverId} 失败: {ex.Message}");
            return false;
        }
    }

    /// <summary>
    /// 停止并移除服务器
    /// </summary>
    /// <param name="serverId">服务器ID</param>
    /// <returns>是否成功</returns>
    public bool StopServer(string serverId)
    {
        if (_servers.TryGetValue(serverId, out var server))
        {
            server.Dispose();
            _servers.Remove(serverId);
            _configs.Remove(serverId);
            
            Console.WriteLine($"服务器 {serverId} 已停止");
            return true;
        }

        Console.WriteLine($"服务器 {serverId} 不存在");
        return false;
    }

    /// <summary>
    /// 获取服务器信息
    /// </summary>
    /// <param name="serverId">服务器ID</param>
    /// <returns>服务器信息</returns>
    public ServerInfo GetServerInfo(string serverId)
    {
        if (_servers.TryGetValue(serverId, out var server) && _configs.TryGetValue(serverId, out var config))
        {
            return new ServerInfo
            {
                ServerId = serverId,
                Address = server.GetAddress(),
                Host = config.Host,
                Port = config.Port,
                MaxConnections = config.MaxConnections,
                IsRunning = true
            };
        }

        return null;
    }

    /// <summary>
    /// 获取所有服务器信息
    /// </summary>
    /// <returns>服务器信息列表</returns>
    public List<ServerInfo> GetAllServers()
    {
        return _servers.Keys.Select(serverId => GetServerInfo(serverId)).Where(info => info != null).ToList();
    }

    /// <summary>
    /// 停止所有服务器
    /// </summary>
    public void StopAllServers()
    {
        var serverIds = _servers.Keys.ToList();
        foreach (string serverId in serverIds)
        {
            StopServer(serverId);
        }
        
        Console.WriteLine($"已停止 {serverIds.Count} 个服务器");
    }
}

/// <summary>
/// 服务器信息类
/// </summary>
public class ServerInfo
{
    public string ServerId { get; set; }
    public string Address { get; set; }
    public string Host { get; set; }
    public int Port { get; set; }
    public int MaxConnections { get; set; }
    public bool IsRunning { get; set; }
    public DateTime StartTime { get; set; } = DateTime.Now;
}

最佳实践

1. 安全考虑

csharp
/// <summary>
/// 安全服务器处理器
/// </summary>
public class SecureServerHandler : AdvancedServerHandler
{
    private readonly HashSet<string> _allowedIPs;
    private readonly Dictionary<string, int> _requestCounts = new Dictionary<string, int>();
    private readonly Timer _rateLimitResetTimer;

    public SecureServerHandler(FBroServerConfig config, HashSet<string> allowedIPs = null) : base(config)
    {
        _allowedIPs = allowedIPs ?? new HashSet<string>();
        
        // 每分钟重置请求计数
        _rateLimitResetTimer = new Timer(ResetRequestCounts, null, TimeSpan.FromMinutes(1), TimeSpan.FromMinutes(1));
    }

    public override void OnClientConnected(IFBroSharpServer server, int connection_id)
    {
        // IP白名单检查
        if (_allowedIPs.Count > 0)
        {
            // 这里需要获取客户端IP,简化示例
            string clientIP = "127.0.0.1"; // 实际需要从连接中获取
            
            if (!_allowedIPs.Contains(clientIP))
            {
                Console.WriteLine($"拒绝连接:IP {clientIP} 不在白名单中");
                server.CloseConnection(connection_id);
                return;
            }
        }

        base.OnClientConnected(server, connection_id);
    }

    protected override void ProcessHttpRequest(IFBroSharpServer server, int connection_id, IFBroSharpRequest request)
    {
        string clientIP = "127.0.0.1"; // 实际需要获取真实IP
        
        // 简单的速率限制
        if (IsRateLimited(clientIP))
        {
            SendErrorResponse(server, connection_id, 429, "Too Many Requests");
            return;
        }

        // 请求路径验证
        string urlPath = new Uri(request.GetURL()).PathAndQuery;
        if (IsSuspiciousPath(urlPath))
        {
            Console.WriteLine($"可疑请求路径: {urlPath}");
            SendErrorResponse(server, connection_id, 403, "Forbidden");
            return;
        }

        base.ProcessHttpRequest(server, connection_id, request);
    }

    /// <summary>
    /// 检查是否被速率限制
    /// </summary>
    private bool IsRateLimited(string clientIP)
    {
        const int maxRequestsPerMinute = 60;
        
        if (!_requestCounts.ContainsKey(clientIP))
        {
            _requestCounts[clientIP] = 0;
        }

        _requestCounts[clientIP]++;
        return _requestCounts[clientIP] > maxRequestsPerMinute;
    }

    /// <summary>
    /// 检查是否为可疑路径
    /// </summary>
    private bool IsSuspiciousPath(string path)
    {
        string[] suspiciousPatterns = { "..", "admin", "config", ".env", "passwd" };
        return suspiciousPatterns.Any(pattern => path.Contains(pattern, StringComparison.OrdinalIgnoreCase));
    }

    /// <summary>
    /// 重置请求计数
    /// </summary>
    private void ResetRequestCounts(object state)
    {
        _requestCounts.Clear();
    }
}

2. 日志记录

csharp
/// <summary>
/// 带日志记录的服务器处理器
/// </summary>
public class LoggingServerHandler : AdvancedServerHandler
{
    private readonly ILogger _logger;

    public LoggingServerHandler(FBroServerConfig config, ILogger logger) : base(config)
    {
        _logger = logger;
    }

    public override void OnClientConnected(IFBroSharpServer server, int connection_id)
    {
        _logger.LogInformation($"客户端连接: ID={connection_id}, 服务器={server.GetAddress()}");
        base.OnClientConnected(server, connection_id);
    }

    public override void OnHttpRequest(IFBroSharpServer server, int connection_id, string client_address, IFBroSharpRequest request)
    {
        var stopwatch = Stopwatch.StartNew();
        
        _logger.LogInformation($"HTTP请求: {request.GetMethod()} {request.GetURL()} 来自 {client_address}");
        
        base.OnHttpRequest(server, connection_id, client_address, request);
        
        stopwatch.Stop();
        _logger.LogInformation($"请求处理完成,耗时: {stopwatch.ElapsedMilliseconds}ms");
    }

    protected override void ProcessHttpRequest(IFBroSharpServer server, int connection_id, IFBroSharpRequest request)
    {
        try
        {
            base.ProcessHttpRequest(server, connection_id, request);
        }
        catch (Exception ex)
        {
            _logger.LogError($"处理HTTP请求异常: {ex.Message}", ex);
            throw;
        }
    }
}

/// <summary>
/// 简单日志接口
/// </summary>
public interface ILogger
{
    void LogInformation(string message);
    void LogError(string message, Exception exception = null);
    void LogWarning(string message);
}

/// <summary>
/// 控制台日志实现
/// </summary>
public class ConsoleLogger : ILogger
{
    public void LogInformation(string message)
    {
        Console.WriteLine($"[INFO] {DateTime.Now:yyyy-MM-dd HH:mm:ss} {message}");
    }

    public void LogError(string message, Exception exception = null)
    {
        Console.WriteLine($"[ERROR] {DateTime.Now:yyyy-MM-dd HH:mm:ss} {message}");
        if (exception != null)
        {
            Console.WriteLine($"[ERROR] Exception: {exception}");
        }
    }

    public void LogWarning(string message)
    {
        Console.WriteLine($"[WARN] {DateTime.Now:yyyy-MM-dd HH:mm:ss} {message}");
    }
}

注意事项

1. 性能优化

  • 连接数限制:合理设置最大连接数避免资源耗尽
  • 文件缓存:对于静态文件考虑实现缓存机制
  • 异步处理:避免在事件处理中执行长时间运行的操作
  • 内存管理:及时清理断开的连接信息

2. 安全考虑

  • 输入验证:验证所有用户输入和请求参数
  • 路径安全:防止路径遍历攻击
  • 速率限制:实现请求速率限制防止DDoS
  • HTTPS支持:生产环境建议使用HTTPS

3. 错误处理

  • 异常捕获:在所有事件处理方法中添加异常处理
  • 资源清理:确保连接和资源得到正确释放
  • 错误响应:提供有意义的错误信息给客户端
  • 日志记录:记录详细的错误信息用于调试

通过这些功能和最佳实践,您可以构建稳定、安全、高性能的FBro内置服务器应用。

FBro服务器事件类传递机制应用

重要提醒

在FBro服务器开发中,需要特别注意事件类传递机制。所有事件回调方法中的接口参数(如IFBroSharpServerIFBroSharpRequestIFBroSharpCallback)都只在该方法的作用域内有效。如果需要在类中保存这些参数供后续使用,必须使用强拷贝机制。

关键点:直接赋值会导致弱拷贝,当事件方法执行完毕后,参数对象就会失效,IsValid()将返回false

正确的服务器事件处理

1. 保存服务器实例的正确方式

csharp
/// <summary>
/// 正确保存服务器实例的示例
/// </summary>
public class ServerInstanceManager : FBroSharpServerHandle
{
    private FBroSharpServer _savedServer; // ✅ 使用具体类型
    private readonly object _lock = new object();

    /// <summary>
    /// 服务器创建事件 - 保存服务器实例
    /// </summary>
    public override void OnServerCreated(IFBroSharpServer server)
    {
        try
        {
            // ✅ 正确方式:创建强拷贝
            _savedServer = new FBroSharpServer(server);
            
            Console.WriteLine($"服务器实例已保存: {_savedServer.GetAddress()}");
            Console.WriteLine("服务器启动完成");
        }
        catch (Exception ex)
        {
            Console.WriteLine($"保存服务器实例失败: {ex.Message}");
        }
    }

    /// <summary>
    /// 服务器销毁事件 - 清理服务器实例
    /// </summary>
    public override void OnServerDestroyed(IFBroSharpServer server)
    {
        try
        {
            lock (_lock)
            {
                if (_savedServer != null)
                {
                    // ✅ 清理保存的实例
                    _savedServer.Dispose(); // 如果有Dispose方法
                    _savedServer = null;
                }
            }
            
            Console.WriteLine("服务器实例已清理");
            Console.WriteLine("服务器已关闭");
        }
        catch (Exception ex)
        {
            Console.WriteLine($"清理服务器实例失败: {ex.Message}");
        }
    }

    /// <summary>
    /// 获取保存的服务器实例
    /// </summary>
    public FBroSharpServer GetSavedServer()
    {
        lock (_lock)
        {
            if (_savedServer != null && _savedServer.IsValid())
            {
                return _savedServer;
            }
            
            Console.WriteLine("保存的服务器实例无效或不存在");
            return null;
        }
    }

    /// <summary>
    /// 使用保存的服务器实例发送响应
    /// </summary>
    public bool SendResponseWithSavedServer(int connectionId, string content, string contentType = "text/html")
    {
        try
        {
            var server = GetSavedServer();
            if (server != null)
            {
                byte[] data = Encoding.UTF8.GetBytes(content);
                server.SendHttp200Response(connectionId, contentType, data);
                return true;
            }
            
            return false;
        }
        catch (Exception ex)
        {
            Console.WriteLine($"使用保存的服务器发送响应失败: {ex.Message}");
            return false;
        }
    }
}

2. 异步请求处理的正确方式

csharp
/// <summary>
/// 支持异步请求处理的服务器处理器
/// </summary>
public class AsyncServerHandler : FBroSharpServerHandleDis
{
    private readonly Dictionary<string, PendingRequest> _pendingRequests = new Dictionary<string, PendingRequest>();
    private readonly object _lock = new object();

    /// <summary>
    /// HTTP请求处理 - 支持异步处理
    /// </summary>
    public override void OnHttpRequest(IFBroSharpServer server, int connection_id, string client_address, IFBroSharpRequest request)
    {
        try
        {
            string requestUrl = request.GetURL();
            Console.WriteLine($"收到请求: {requestUrl} 来自 {client_address}");

            // 检查是否需要异步处理
            if (ShouldProcessAsync(requestUrl))
            {
                // ✅ 为异步处理创建强拷贝
                var requestId = Guid.NewGuid().ToString();
                var pendingRequest = new PendingRequest
                {
                    Id = requestId,
                    Server = new FBroSharpServer(server),        // 强拷贝服务器
                    Request = new FBroSharpRequest(request),     // 强拷贝请求
                    ConnectionId = connection_id,
                    ClientAddress = client_address,
                    ReceivedTime = DateTime.Now
                };

                lock (_lock)
                {
                    _pendingRequests[requestId] = pendingRequest;
                }

                // 异步处理请求
                Task.Run(() => ProcessRequestAsync(requestId));
            }
            else
            {
                // 同步处理(在作用域内直接使用参数)
                base.OnHttpRequest(server, connection_id, client_address, request);
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine($"处理HTTP请求失败: {ex.Message}");
            SendErrorResponse(server, connection_id, 500, "Internal Server Error");
        }
    }

    /// <summary>
    /// 异步处理请求
    /// </summary>
    private async Task ProcessRequestAsync(string requestId)
    {
        PendingRequest pendingRequest = null;
        
        try
        {
            lock (_lock)
            {
                _pendingRequests.TryGetValue(requestId, out pendingRequest);
            }

            if (pendingRequest?.Server != null && pendingRequest.Server.IsValid())
            {
                Console.WriteLine($"开始异步处理请求: {requestId}");

                // ✅ 使用强拷贝的对象进行异步操作
                await SimulateAsyncWork();

                string responseContent = GenerateAsyncResponse(pendingRequest);
                byte[] responseData = Encoding.UTF8.GetBytes(responseContent);

                // 发送响应
                pendingRequest.Server.SendHttp200Response(pendingRequest.ConnectionId, "application/json", responseData);
                
                Console.WriteLine($"异步请求处理完成: {requestId}");
            }
            else
            {
                Console.WriteLine($"异步请求处理失败,服务器对象无效: {requestId}");
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine($"异步处理请求 {requestId} 失败: {ex.Message}");
        }
        finally
        {
            // ✅ 清理资源
            CleanupPendingRequest(requestId);
        }
    }

    /// <summary>
    /// 判断是否需要异步处理
    /// </summary>
    private bool ShouldProcessAsync(string url)
    {
        return url.Contains("/api/async/") || url.Contains("/slow-operation");
    }

    /// <summary>
    /// 模拟异步工作
    /// </summary>
    private async Task SimulateAsyncWork()
    {
        // 模拟数据库查询、文件IO或网络请求
        await Task.Delay(2000); // 模拟2秒的异步操作
    }

    /// <summary>
    /// 生成异步响应
    /// </summary>
    private string GenerateAsyncResponse(PendingRequest request)
    {
        var response = new
        {
            requestId = request.Id,
            processedAt = DateTime.Now,
            requestUrl = request.Request?.GetURL(),
            clientAddress = request.ClientAddress,
            processingTime = DateTime.Now - request.ReceivedTime,
            message = "异步请求处理完成"
        };

        return JsonConvert.SerializeObject(response, Formatting.Indented);
    }

    /// <summary>
    /// 清理待处理请求
    /// </summary>
    private void CleanupPendingRequest(string requestId)
    {
        lock (_lock)
        {
            if (_pendingRequests.TryGetValue(requestId, out var request))
            {
                // ✅ 清理强拷贝的对象
                try
                {
                    request.Server?.Dispose();
                    request.Request?.Dispose();
                }
                catch (Exception ex)
                {
                    Console.WriteLine($"清理请求资源失败: {ex.Message}");
                }

                request.Server = null;
                request.Request = null;
                _pendingRequests.Remove(requestId);
            }
        }
    }

    /// <summary>
    /// 清理所有待处理请求
    /// </summary>
    public void CleanupAllPendingRequests()
    {
        lock (_lock)
        {
            foreach (var kvp in _pendingRequests)
            {
                try
                {
                    kvp.Value.Server?.Dispose();
                    kvp.Value.Request?.Dispose();
                }
                catch (Exception ex)
                {
                    Console.WriteLine($"清理待处理请求失败: {ex.Message}");
                }
            }

            _pendingRequests.Clear();
            Console.WriteLine("所有待处理请求已清理");
        }
    }
}

/// <summary>
/// 待处理请求信息
/// </summary>
public class PendingRequest
{
    public string Id { get; set; }
    public FBroSharpServer Server { get; set; }    // 强拷贝的服务器对象
    public FBroSharpRequest Request { get; set; }  // 强拷贝的请求对象
    public int ConnectionId { get; set; }
    public string ClientAddress { get; set; }
    public DateTime ReceivedTime { get; set; }
}

3. 回调对象的正确处理

csharp
/// <summary>
/// 正确处理回调对象的示例
/// </summary>
public class CallbackAwareServerHandler : FBroSharpServerHandleDis
{
    private readonly Dictionary<string, SavedCallback> _callbacks = new Dictionary<string, SavedCallback>();
    private readonly object _lock = new object();

    /// <summary>
    /// WebSocket请求处理 - 保存回调对象
    /// </summary>
    public override void OnWebSocketRequest(IFBroSharpServer server, int connection_id, string client_address, 
                IFBroSharpRequest request, IFBroSharpCallback callback)
    {
        try
        {
            string callbackId = Guid.NewGuid().ToString();
            
            // ✅ 创建强拷贝保存回调对象
            var savedCallback = new SavedCallback
            {
                Id = callbackId,
                Server = new FBroSharpServer(server),
                Request = new FBroSharpRequest(request),
                Callback = new FBroSharpCallback(callback), // 强拷贝回调对象
                ConnectionId = connection_id,
                ClientAddress = client_address,
                CreatedTime = DateTime.Now
            };

            lock (_lock)
            {
                _callbacks[callbackId] = savedCallback;
            }

            Console.WriteLine($"WebSocket回调已保存: {callbackId}");
            Console.WriteLine($"请求URL: {request.GetURL()}");

            // 可以在这里启动异步处理或延迟回调
            ScheduleDelayedCallback(callbackId, TimeSpan.FromSeconds(5));
        }
        catch (Exception ex)
        {
            Console.WriteLine($"处理WebSocket请求失败: {ex.Message}");
        }
    }

    /// <summary>
    /// 安排延迟回调
    /// </summary>
    private void ScheduleDelayedCallback(string callbackId, TimeSpan delay)
    {
        Timer timer = null;
        timer = new Timer((_) =>
        {
            try
            {
                ExecuteSavedCallback(callbackId);
            }
            finally
            {
                timer?.Dispose();
            }
        }, null, delay, Timeout.InfiniteTimeSpan);
    }

    /// <summary>
    /// 执行保存的回调
    /// </summary>
    private void ExecuteSavedCallback(string callbackId)
    {
        SavedCallback savedCallback = null;

        lock (_lock)
        {
            _callbacks.TryGetValue(callbackId, out savedCallback);
        }

        if (savedCallback?.Callback != null && savedCallback.Callback.IsValid())
        {
            try
            {
                Console.WriteLine($"执行延迟回调: {callbackId}");

                // ✅ 使用强拷贝的回调对象
                // 这里可以根据具体的回调类型执行相应操作
                // savedCallback.Callback.Continue(); // 示例方法
                
                Console.WriteLine($"回调执行完成: {callbackId}");
            }
            catch (Exception ex)
            {
                Console.WriteLine($"执行回调失败 {callbackId}: {ex.Message}");
            }
            finally
            {
                // ✅ 清理回调
                CleanupCallback(callbackId);
            }
        }
        else
        {
            Console.WriteLine($"回调对象无效: {callbackId}");
            CleanupCallback(callbackId);
        }
    }

    /// <summary>
    /// 清理回调对象
    /// </summary>
    private void CleanupCallback(string callbackId)
    {
        lock (_lock)
        {
            if (_callbacks.TryGetValue(callbackId, out var callback))
            {
                try
                {
                    callback.Server?.Dispose();
                    callback.Request?.Dispose();
                    callback.Callback?.Dispose();
                }
                catch (Exception ex)
                {
                    Console.WriteLine($"清理回调资源失败: {ex.Message}");
                }

                callback.Server = null;
                callback.Request = null;
                callback.Callback = null;
                _callbacks.Remove(callbackId);

                Console.WriteLine($"回调已清理: {callbackId}");
            }
        }
    }

    /// <summary>
    /// 清理所有回调
    /// </summary>
    public void CleanupAllCallbacks()
    {
        lock (_lock)
        {
            foreach (var kvp in _callbacks)
            {
                try
                {
                    kvp.Value.Server?.Dispose();
                    kvp.Value.Request?.Dispose();
                    kvp.Value.Callback?.Dispose();
                }
                catch (Exception ex)
                {
                    Console.WriteLine($"清理回调失败: {ex.Message}");
                }
            }

            _callbacks.Clear();
            Console.WriteLine("所有回调已清理");
        }
    }
}

/// <summary>
/// 保存的回调信息
/// </summary>
public class SavedCallback
{
    public string Id { get; set; }
    public FBroSharpServer Server { get; set; }
    public FBroSharpRequest Request { get; set; }
    public FBroSharpCallback Callback { get; set; }
    public int ConnectionId { get; set; }
    public string ClientAddress { get; set; }
    public DateTime CreatedTime { get; set; }
}

服务器事件参数强拷贝对照表

事件方法参数类型强拷贝方式使用场景
OnServerCreatedIFBroSharpServernew FBroSharpServer(server)保存服务器实例供全局使用
OnHttpRequestIFBroSharpServernew FBroSharpServer(server)异步请求处理
OnHttpRequestIFBroSharpRequestnew FBroSharpRequest(request)延迟请求处理
OnWebSocketRequestIFBroSharpCallbacknew FBroSharpCallback(callback)延迟回调执行
OnClientConnectedIFBroSharpServernew FBroSharpServer(server)连接管理和统计

常见错误和解决方案

错误1:直接保存事件参数

csharp
// ❌ 错误方式
public class BadServerHandler : FBroSharpServerHandle
{
    private IFBroSharpServer _server; // 错误:使用接口类型

    public override void OnServerCreated(IFBroSharpServer server)
    {
        _server = server; // 错误:弱拷贝,会失效
    }

    public void UseServer()
    {
        _server.SendHttp200Response(1, "text/html", new byte[0]); // 会失败
    }
}

// ✅ 正确方式
public class GoodServerHandler : FBroSharpServerHandle
{
    private FBroSharpServer _server; // 正确:使用具体类型

    public override void OnServerCreated(IFBroSharpServer server)
    {
        _server = new FBroSharpServer(server); // 正确:强拷贝
    }

    public void UseServer()
    {
        if (_server != null && _server.IsValid())
        {
            _server.SendHttp200Response(1, "text/html", new byte[0]); // 正常工作
        }
    }
}

错误2:在异步方法中直接使用事件参数

csharp
// ❌ 错误方式
public override void OnHttpRequest(IFBroSharpServer server, int connection_id, 
            string client_address, IFBroSharpRequest request)
{
    // 错误:在异步任务中直接使用事件参数
    Task.Run(async () =>
    {
        await Task.Delay(1000);
        // 这里server和request很可能已经失效
        server.SendHttp200Response(connection_id, "text/html", Encoding.UTF8.GetBytes("Response"));
    });
}

// ✅ 正确方式
public override void OnHttpRequest(IFBroSharpServer server, int connection_id, 
            string client_address, IFBroSharpRequest request)
{
    // 正确:创建强拷贝用于异步操作
    var serverCopy = new FBroSharpServer(server);
    var requestCopy = new FBroSharpRequest(request);
    
    Task.Run(async () =>
    {
        try
        {
            await Task.Delay(1000);
            if (serverCopy != null && serverCopy.IsValid())
            {
                serverCopy.SendHttp200Response(connection_id, "text/html", Encoding.UTF8.GetBytes("Response"));
            }
        }
        finally
        {
            // 清理资源
            serverCopy?.Dispose();
            requestCopy?.Dispose();
        }
    });
}

性能和内存优化建议

  1. 按需拷贝:只在确实需要保存参数时才创建强拷贝
  2. 及时清理:使用完毕后立即清理强拷贝对象
  3. 生命周期管理:使用using语句或try-finally确保资源清理
  4. 监控无效对象:定期检查和清理失效的对象引用
csharp
/// <summary>
/// 优化的服务器处理器示例
/// </summary>
public class OptimizedServerHandler : FBroSharpServerHandle
{
    /// <summary>
    /// 使用using语句确保资源清理
    /// </summary>
    public override void OnHttpRequest(IFBroSharpServer server, int connection_id, 
                string client_address, IFBroSharpRequest request)
    {
        // 只在需要异步处理时才创建拷贝
        if (RequiresAsyncProcessing(request.GetURL()))
        {
            using (var serverCopy = new FBroSharpServer(server))
            using (var requestCopy = new FBroSharpRequest(request))
            {
                ProcessAsyncRequest(serverCopy, requestCopy, connection_id);
            } // 自动清理资源
        }
        else
        {
            // 同步处理,直接使用参数
            ProcessSyncRequest(server, request, connection_id);
        }
    }

    private bool RequiresAsyncProcessing(string url)
    {
        return url.Contains("/async/") || url.Contains("/slow/");
    }

    private void ProcessAsyncRequest(FBroSharpServer server, FBroSharpRequest request, int connectionId)
    {
        Task.Run(async () =>
        {
            try
            {
                await Task.Delay(1000); // 异步操作
                if (server.IsValid())
                {
                    var response = "Async response completed";
                    server.SendHttp200Response(connectionId, "text/plain", Encoding.UTF8.GetBytes(response));
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine($"异步处理失败: {ex.Message}");
            }
        });
    }

    private void ProcessSyncRequest(IFBroSharpServer server, IFBroSharpRequest request, int connectionId)
    {
        var response = "Sync response";
        server.SendHttp200Response(connectionId, "text/plain", Encoding.UTF8.GetBytes(response));
    }
}

通过遵循这些FBro事件类传递机制的最佳实践,您可以避免常见的对象失效问题,构建更加稳定可靠的FBro服务器应用。

如果文档对您有帮助,欢迎 请喝咖啡 ☕ | 软件发布 | 源码购买