sgcWebSockets 2026.5 — 速率限制器、熔断器、API 密钥、MCP OAuth 与更快的 IOCP

· 版本发布

sgcWebSockets 2026.5 是一次内容丰富的版本发布。三个新的基础设施组件将 WebSocket / HTTP 服务器升级为生产级 API 网关:一个功能齐全的速率限制器、一个客户端熔断器,以及一个支持完整生命周期的 API 密钥管理器。在协议层面,新增了构建于通用 Lightstreamer TLCP 2.5 实现之上的 Forex.com 客户端,MCP Server 内置了 OAuth 2.1 流程,可直接对接如 claude.ai 等基于浏览器的 MCP 客户端;IOCP(Windows)与 EPOLL(Linux)I/O 引擎获得了六项可衡量的性能提升。还包含了一个早期的后量子原语:sgcKEM_CreateMLKEM768Keys,用于生成 ML-KEM-768 密钥对。

本文将通过可直接粘贴使用的 Delphi 代码片段,依次介绍这些亮点。

TsgcWSRateLimiter — 开箱即用的 API 速率限制

在服务器旁放置一个 TsgcWSRateLimiter,便可获得基于令牌桶、滑动窗口或固定窗口的速率限制,支持按 IP、按 API 密钥、按用户或按端点模式进行限制,外加按日/按月配额和突发保护。该组件是线程安全的,并将状态持久化到磁盘(这样服务器重启后不会让每个客户端获得全新的额度)。

uses
  sgcWebSocket_Server_RateLimiter;

var
  oRL: TsgcWSRateLimiter;
  oResult: TsgcRateLimitResult;
begin
  oRL := TsgcWSRateLimiter.Create(nil);
  try
    oRL.TokenBucket.Enabled    := True;
    oRL.TokenBucket.Capacity   := 100;     // burst size
    oRL.TokenBucket.RefillRate := 10;      // tokens / interval
    oRL.TokenBucket.RefillIntervalMs := 1000;

    oRL.PerIP.Enabled       := True;
    oRL.PerIP.MaxRequests   := 60;
    oRL.PerIP.WindowSec     := 60;

    // Consume one token for the current request
    oResult := oRL.Consume('ip:' + vClientIP);
    if not oResult.Allowed then
      RespondHTTP(429, 'Retry-After: ' + IntToStr(oResult.RetryAfterSec));
  finally
    oRL.Free;
  end;
end;

规则解析器会依次遍历 PerEndpoint(支持通配符匹配)、PerAPIKeyPerUser,最后是 PerIPOnThrottledOnQuotaExceededOnStateChange 事件可让您记录或覆盖每一个判定。

演示:Demos\04.WebSocket_Other_Samples\14.RateLimiter — 一个洪流式生成请求的客户端,对应一台发布实时统计和拒绝原因的服务器。

TsgcWSCircuitBreaker — 客户端故障隔离

当上游 API(api.openai.com、支付网关或内部微服务)开始失败或变慢时,挂在 TCP 超时上会耗费连接、线程和资金。TsgcWSCircuitBreaker 在任意 TsgcHTTPAPI_client 子类之上实现了经典的三态模式(关闭 / 打开 / 半开),具备滚动时间窗口、慢调用检测、可选的回退响应以及按端点的覆盖配置。

uses
  sgcWebSocket_CircuitBreaker;

var
  oCB: TsgcWSCircuitBreaker;
begin
  oCB := TsgcWSCircuitBreaker.Create(nil);
  try
    oCB.Thresholds.FailureCount        := 5;
    oCB.Thresholds.FailureRatePercent  := 50;
    oCB.Thresholds.SlowCallDurationMs  := 2000;
    oCB.Thresholds.SlowCallRatePercent := 80;
    oCB.TimeWindow.RollingWindowSec    := 60;
    oCB.Recovery.CooldownSec           := 30;
    oCB.Recovery.HalfOpenTrialCalls    := 3;

    oCB.Fallback.Enabled        := True;
    oCB.Fallback.UseLastSuccess := True;

    if oCB.IsCallAllowed('openai') then
    try
      vResponse := oOpenAI.ChatCompletion(...);
      oCB.RecordSuccess('openai');
    except
      on E: Exception do
      begin
        oCB.RecordFailure('openai', E.ClassName);
        raise;
      end;
    end
    else
      vResponse := 'service temporarily unavailable';
  finally
    oCB.Free;
  end;
end;

在 Delphi 2009+ 上还提供了一个单行封装:oCB.Execute('openai', procedure begin oOpenAI.ChatCompletion(...) end); — 成功 / 失败的记录会自动完成。

演示:Demos\04.WebSocket_Other_Samples\15.CircuitBreaker

TsgcWSAPIKeyManager — 单组件管理密钥生命周期

大多数 "WebSocket API" 服务器都需要 API 密钥:签发、校验、撤销、轮换。TsgcWSAPIKeyManager 封装了完整的生命周期,包括基于作用域的授权、可选的静态哈希、过期、审计日志,以及内置的轮换宽限期,使旧密钥在轮换后于可配置的时间窗口内继续有效。

uses
  sgcWebSocket_Server_APIKeyManager;

var
  oKM: TsgcWSAPIKeyManager;
  vKey, vNewKey: string;
begin
  oKM := TsgcWSAPIKeyManager.Create(nil);
  try
    oKM.Generation.Length := 40;
    oKM.Generation.Prefix := 'sgc_';
    oKM.Hashing.Enabled   := True;        // store SHA-256 hash, not the plaintext
    oKM.Rotation.GracePeriodSec := 86400; // old key valid for 24h after rotation
    oKM.Expiration.DefaultTTLSec := 30 * 86400;

    // Issue a key for tenant "acme" with read+write scopes, expiring in 7 days
    vKey := oKM.IssueKey('acme', ['read', 'write'], 7 * 86400);

    // Validate the key on each request, optionally requiring a scope
    if not oKM.ValidateKey(vKey, 'read', vClientIP) then
      RespondHTTP(401, 'invalid api key');

    // Rotate a key (returns the new plaintext; old key remains valid for GracePeriodSec)
    oKM.RotateKey(vKey, vNewKey);
  finally
    oKM.Free;
  end;
end;

该组件可以通过 IsRequestAuthorized 直接从入站 HTTP 头或查询字符串中读取密钥,因此您无需自行编写提取逻辑。

演示:Demos\04.WebSocket_Other_Samples\16.APIKeyManager

Forex.com 客户端 + 通用 Lightstreamer

新的 TsgcWSAPI_Forex 客户端提供了对 Forex.com 的统一 REST + 流式访问(登录、心跳、行情监视、持仓、订单、交易历史、模拟交易)。它构建于全新的 TsgcWSPClient_Lightstreamer 组件之上:这是一个通用的 Lightstreamer TLCP 2.5 客户端,实现了 create_sessionbind_sessioncontrol(订阅 / 取消订阅)以及 LOOP 自动重新绑定 + 重连后订阅重放。该 Lightstreamer 客户端本身可以独立复用,相同的代码基础同样适用于 IG Markets 以及任何基于 Lightstreamer 的行情源。

uses sgcHTTP_API_Forex;

var oFX: TsgcWSAPI_Forex;
begin
  oFX := TsgcWSAPI_Forex.Create(nil);
  oFX.UserName  := 'demo-user';
  oFX.Password  := 'secret';
  oFX.AppKey    := 'your-app-key';
  oFX.Login;
  oFX.SubscribePrices(['EUR/USD', 'GBP/USD', 'XAU/USD']);
  oFX.OnPriceUpdate := procedure(const aSymbol: string; aBid, aAsk: Double)
                      begin
                        ShowMessage(Format('%s %.5f / %.5f', [aSymbol, aBid, aAsk]));
                      end;
end;

完整的 GUI 演示位于 Demos\05.Crypto\22.Forex — 包含登录、连通性心跳、实时行情监视、持仓、活动订单、交易历史、止损 / 限价历史以及模拟交易,凭据会被持久化到 sgcForexDemo.ini

MCP Server — 面向浏览器 MCP 客户端的 OAuth 2.1

MCP Server 现在可以直接与基于浏览器的 MCP 连接器(例如 claude.ai)通信,无需外部授权服务器。它会自动发布 MCP 浏览器连接器规范所要求的四个 OAuth 发现 / 注册端点,运行带有 HTML 同意页面的 PKCE-S256 授权流程,并签发刷新令牌:

CORS 在内联中处理:OPTIONS 预检在身份验证之前返回 204,并附带完整的 Access-Control-* 头;每个响应都会带有一个反射请求来源的 Access-Control-Allow-Origin 头,以及一个 Strict-Transport-Security: max-age=31536000 HSTS 头。

IOCP 和 EPOLL:六项调优收益

Windows IOCP 与 Linux EPOLL I/O 引擎获得了一轮聚焦于性能与可调优性的改进。

IOCP(Windows)

oServer.Bindings.Add.Port := 443;
oServer.IOHandler := TsgcIndy_IOHandler_IO_IOCP.Create(oServer);
with TsgcIndy_IOHandler_IO_IOCP(oServer.IOHandler) do
begin
  SendBufferSize    := 256 * 1024;
  ReceiveBufferSize := 256 * 1024;
  TCPNoDelay        := True;
  Engine.ThreadAffinity := True;
end;

EPOLL(Linux)

共享

IOCP / EPOLL 的 worker 池过去会在每次迭代时都执行 sleep(1)包括刚刚处理完一个任务之后 — 实际上将每个 worker 限制在约 1,000 ops/s,即使队列已满也是如此。现在只要有等待中的工作,就会跳过该 sleep,这一上限随之消失。

HTTP.sys:可选的高性能模式

HTTP.sys 服务器新增了带 OperatingMode 选择器的 FineTune 属性。默认的 ompClassic 保留现有行为。新的 ompHighPerf 模式实现了 MSDN 推荐的 N-workers × M-pre-posted-async-receives 模式 — 即面向高吞吐 HTTP.sys 部署所推荐的架构 — 并将其封装在单个属性之下:

oServer := TsgcWebSocketHTTPServer.Create(nil);
oServer.HTTP2Options.SecureOptions.HTTPAPI := True;   // use HTTP.sys
oServer.FineTune.OperatingMode := ompHighPerf;
oServer.FineTune.WorkerCount   := 8;
oServer.FineTune.PrePostedReceivesPerWorker := 16;
oServer.Active := True;

THttpServerRequestTHttpServerResponse 也进行了扩展,新增了若干字段,涵盖此前只能通过手动解析获得的详细信息。

后量子原语:ML-KEM-768

一个小而具有前瞻性的新增:sgcKEM_CreateMLKEM768Keys 生成 ML-KEM-768(FIPS 203 / Kyber-768)密钥对,同时输出 PEM 和原始字节两种形式。ML-KEM 是 NIST 标准化的后量子 KEM,并在 IETF 路线图中用于混合 TLS 1.3(X25519MLKEM768)。这为在即将到来的 OpenSSL 3.5 / 3.6 基线之前实验 PQ 就绪握手扫清了障碍。

uses sgcKEM;

var vPubPEM, vPrivPEM: string; vPubRaw, vPrivRaw: TBytes;
begin
  sgcKEM_CreateMLKEM768Keys(vPubPEM, vPrivPEM, vPubRaw, vPrivRaw);
  TFile.WriteAllText('mlkem768_pub.pem', vPubPEM);
  TFile.WriteAllText('mlkem768_priv.pem', vPrivPEM);
end;

可靠性与一致性修复

本次 bug 修复批次解决了一长串 MCP、HTTP.sys、IOCP 和 HTTP/2 的问题。要点如下:

升级

对于现有的 2026.4 项目,2026.5 是一次开箱即用的升级。未对现有组件进行任何接口变更;新的速率限制 / 熔断器 / API 密钥组件是附加且可选启用的。HTTP.sys 高性能模式被门控在 FineTune.OperatingMode := ompHighPerf 之后 — 现有代码保持在经典路径上。

拥有有效订阅的客户可从客户专区下载新版本。试用用户可在 esegece.com/products/sgcwebsockets/sgcwebsockets-download 获取更新后的安装程序。

有问题、反馈或需要迁移帮助?联系我们 — 您会收到代码作者本人的回复。