sgcWebSockets 2026.5は内容の濃いリリースです。3つの新しいインフラストラクチャコンポーネントによって、WebSocket / HTTPサーバーは本番グレードのAPIゲートウェイへと進化します。フル機能のレートリミッター、クライアントサイドのサーキットブレーカー、そして完全なライフサイクル対応のAPIキーマネージャーです。プロトコル側では、汎用的なLightstreamer TLCP 2.5実装の上に構築された新しいForex.comクライアントが追加され、MCPサーバーには組み込みのOAuth 2.1フローが搭載されたため、claude.aiなどのブラウザベースのMCPクライアントと直接接続できるようになりました。IOCP(Windows)とEPOLL(Linux)のI/Oエンジンは、6つの計測可能なパフォーマンス向上を獲得しました。さらに、初期段階のポスト量子プリミティブとして、ML-KEM-768鍵ペア生成用のsgcKEM_CreateMLKEM768Keysも追加されています。
本記事では、新コンポーネント用の貼り付け可能な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(ワイルドカードマッチ)から始まり、次にPerAPIKey、PerUser、最後にPerIPの順に処理されます。OnThrottled、OnQuotaExceeded、OnStateChangeイベントを使えば、すべての判定をログ出力したり上書きしたりできます。
デモ: Demos\04.WebSocket_Other_Samples\14.RateLimiter — ライブ統計と拒否理由を公開するサーバーに対して、フラッド生成クライアントを実行します。
TsgcWSCircuitBreaker — クライアントサイドの障害分離
上流のAPI(api.openai.com、決済ゲートウェイ、内部マイクロサービスなど)が失敗し始めたり遅くなったりすると、TCPタイムアウトでハングすることにより、接続、スレッド、そしてコストが浪費されます。TsgcWSCircuitBreakerは、任意のTsgcHTTPAPI_clientサブクラスの上に古典的な3状態パターン(クローズ / オープン / ハーフオープン)を実装し、ローリングタイムウィンドウ、低速呼び出し検知、オプションのフォールバック応答、エンドポイント単位のオーバーライドを提供します。
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以降では、1行ラッパーも利用可能です: 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 + ストリーミングアクセス(ログイン、ping、マーケットウォッチ、ポジション、注文、取引履歴、トレードシミュレーション)を提供します。これは、create_session、bind_session、control(subscribe / unsubscribe)、そして再接続後のLOOP自動再バインド + サブスクリプション再生を実装した、汎用Lightstreamer TLCP 2.5クライアントである真新しいTsgcWSPClient_Lightstreamerコンポーネントの上に構築されています。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にあります — ログイン、接続性ping、ライブマーケットウォッチ、ポジション、アクティブ注文、取引履歴、ストップ / リミット履歴、トレードシミュレーション、そしてsgcForexDemo.iniへの認証情報の永続化を備えています。
MCPサーバー — ブラウザベースMCPクライアント向けOAuth 2.1
MCPサーバーは外部の認可サーバーなしで、ブラウザベースのMCPコネクター(claude.aiなど)と直接対話できるようになりました。MCPブラウザーコネクター仕様で必要とされる4つのOAuthディスカバリー / 登録エンドポイントを自動的に公開し、HTMLの同意画面付きのPKCE-S256認可フローを実行し、リフレッシュトークンを発行します:
GET /.well-known/oauth-authorization-server— RFC 8414メタデータ。GET /.well-known/oauth-protected-resource— RFC 9728保護リソースメタデータ。POST /oauth/register— RFC 7591動的クライアント登録。GET /oauth/authorize— HTML同意フォーム。POST /oauth/token— PKCE S256 + リフレッシュトークン。
CORSはインラインで処理されます: OPTIONSプリフライトは認証より前に、完全なAccess-Control-*ヘッダー付きで204を返し、すべてのレスポンスはリクエストオリジンを反映したAccess-Control-Allow-OriginとStrict-Transport-Security: max-age=31536000 HSTSヘッダーを伴います。
IOCPとEPOLL: 6つのチューニング向上
Windows IOCPおよびLinux EPOLLのI/Oエンジンは、パフォーマンスとチューナビリティに焦点を絞った作業を受けました。
IOCP(Windows)
ThreadAffinity(デフォルトFalse)がTsgcIndy_IO_Engineに追加 —SetThreadAffinityMask経由で、エンジンスレッドを論理コアにラウンドロビンでピン留めします。高コア数システムでのコア間キャッシュトラフィックを削減します。Metrics— クリティカルセクションのもとで更新される新しいTsgcIndy_IO_EngineMetricsレコード(AcceptsPosted、AcceptsCompleted、ReadsPosted、ReadsCompleted、ActiveConnections、BytesRead、BytesWritten)。もう推測する必要はありません。SendBufferSize、ReceiveBufferSize、TCPNoDelayがTsgcIndy_IOHandler_IO_IOCPに追加 —AfterAccept内でsetsockopt経由で適用されるため、接続単位のチューニングにカスタムOnConnectハンドラーが不要になりました。TsgcPerIoDataPoolの容量を256から2048に引き上げ、高い接続並行性下でのGetMem/FreeMemヒープフォールバックを回避します。ループバックベンチマークでWebSocketスループット+15〜18%。
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)
AcceptBatchSize、WaitTimeoutMS、HandshakeTimeoutMS— acceptループとスローロリス対策をチューニングします。- EPOLLOUT駆動の書き込みバックプレッシャー —
send()が部分的な書き込みでEAGAINを返した場合、残りのバイトは接続単位のペンディングバッファに取り込まれ、ソケットはEPOLLIN|EPOLLOUTで再アームされます。リアクタはバイトをドロップしたりワーカーをブロックしたりする代わりに、次のEPOLLOUTイベントで残りをフラッシュします。
共通
IOCP / EPOLLワーカープールは、これまでタスク処理直後を含むすべての反復でsleep(1)を行っており — キューがフルでも各ワーカーが事実上約1,000 ops/sに制限されていました。作業が待機している間はスリープがスキップされるようになり、この上限が取り除かれました。
HTTP.sys: オプトイン型の高性能モード
HTTP.sysサーバーにOperatingModeセレクター付きのFineTuneプロパティが追加されました。デフォルトのompClassicは既存の動作を維持します。新しいompHighPerfモードは、MSDN N-ワーカー × M-プリポストされた非同期受信パターン — 高スループット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;
THttpServerRequestとTHttpServerResponseも、これまで手動パースでしか取得できなかった詳細をカバーする追加フィールドで拡張されました。
ポスト量子プリミティブ: ML-KEM-768
小さいながらも将来を見据えた追加: sgcKEM_CreateMLKEM768Keysは、ML-KEM-768(FIPS 203 / Kyber-768)の鍵ペアをPEM形式と生バイト形式の両方で生成します。ML-KEMはNISTによって標準化されたポスト量子KEMであり、ハイブリッドTLS 1.3(X25519MLKEM768)のIETFロードマップに含まれています。これにより、来る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;
信頼性と準拠性の修正
バグ修正バッチは、MCP、HTTP.sys、IOCP、HTTP/2の長い課題リストをクローズします。ハイライト:
- MCPサーバー — 認証情報が欠落しているか無効な場合、
500 Internal Server Errorではなく、保護リソースメタデータを指すWWW-Authenticate: Bearerヘッダー付きの401 Unauthorizedが返されるようになりました。ブラウザベースのMCPクライアントによるOAuthディスカバリーに必要です。 - MCPサーバー —
OPTIONSリクエストがJSON-RPCパーサーに到達しなくなりました(以前は500 "Invalid jsonrpc Value"を返していました)。CORSプリフライトは認証前およびMCPボディパーサー前に処理されるようになりました。 - MCPサーバー — 非ASCII文字を含むツール説明、プロンプトメッセージ、リソースコンテンツが接続を切断しなくなりました(JSONボディが宣言された
charset=utf-8と一致するようになりました)。 - MCPサーバー — 非ASCII文字を含む
tool/prompt/resource/root/template/ completion-refおよびcompletion-argumentのnameフィールドが、生のUTF-16コードポイントではなくJSONの\uXXXXエスケープとして正しく出力・読み取りされるようになりました。 - HTTP APIリクエストボディ —
TsgcWSComponent_Server.DoHTTPRequestAPIはエンコーディングを指定せずにReadStringFromStreamを呼び出していたため、ASCIIをデフォルトとして使用し、イベントハンドラーが見る前にすべての非ASCIIバイトを?に置換していました。修正済み。 - HTTP.sysサーバー —
TsgcHTTPServerAPI.DoExecuteのERROR_MORE_DATAでのコンテキストリーク。acceptループは同じリクエストID上でバッファを拡大してHttpReceiveHttpRequestをリトライし、すべてのエラーパスで孤立したコンテキストを解放するようになりました。 - HTTP.sysサーバー —
TsgcWSConnectionServer_HTTPAPI.DoSendHTTP_Responseが、最終応答にHTTP_SEND_RESPONSE_FLAG_MORE_DATAを設定しなくなりました。 - IOCP IOHandler —
TsgcIndy_IO_Engine_IOCP_Base.DoStopThreadsがスレッドHANDLEではなくDWORDのスレッドID(FThreadsId)の配列に対してWaitForMultipleObjectsを呼び出していました。修正済み。 - IOCP IOHandler — シャットダウン時およびソケット単位のクローズ時に、ソケット上の保留中I/O操作がキャンセルされるようになりました。
- IOCP IOHandler —
DoFreePerIoData内の脆弱なOverlapped.Internal = STATUS_PENDINGプローブが、TsgcPerIoData上の明示的なCompleted: Booleanフラグに置き換えられました。 - HTTP/2 WebBrokerBridge — DataSnap RESTがHTTP/2の
HEADERSのみのフレームを処理した際の、TsgcWSHTTPServer.OnHTTP2RequestEvent内のsgcFree(oResponse)でのInvalid pointer operation。
アップグレード
2026.5は既存の2026.4プロジェクトに対するドロップインアップグレードです。既存のコンポーネントにインターフェース変更はありません。新しいレートリミット / サーキットブレーカー / APIキーコンポーネントは追加的かつオプトインです。HTTP.sys高性能モードはFineTune.OperatingMode := ompHighPerfでゲートされています — 既存のコードはクラシックパスのままです。
アクティブなサブスクリプションをお持ちのお客様は、カスタマーエリアから新ビルドをダウンロードできます。トライアルユーザーの方は、esegece.com/products/sgcwebsockets/sgcwebsockets-downloadで更新されたインストーラーを入手できます。
ご質問、フィードバック、または移行のサポートが必要ですか?お問い合わせ — コードを書いた本人から返信が届きます。
