sgcWebSockets 2026.7 のテーマは、本番環境で動かすことです。WebSocket アプリケーションを複数のサーバーに分散させながら、チャンネル、pub/sub、プレゼンスをすべてのサーバーにまたがって動作させられるようになりました。チャンネルは直近のメッセージを記憶できるので、切断して戻ってきたクライアントは、その間に見逃したものを受け取れます。クライアントは足並みをそろえてサーバーに殺到する代わりに、指数バックオフとジッターで再接続します。送信キューに上限を設けられるので、遅いコンシューマー 1 つがサーバーのメモリを食い尽くすことはありません。そして HTTP クライアントには、資格情報を漏らすリダイレクト、ダウングレードされた TLS、サイズ制限のないレスポンスに対する一連の防御が加わりました。
さらに、Delphi 向けの async / await レイヤー、HTTP サーバーの gzip と deflate、新しい HTTP QUERY メソッド、エンドツーエンド暗号化の ID 検証、MCP クライアントの OAuth2、そして長い修正リストがあります。この記事はそのガイドツアーです。各セクションから、その機能を詳しく扱った記事にリンクしています。
複数サーバーにまたがるクラスタリング
新しい TsgcWSCluster コンポーネントは、複数の sgcWebSockets サーバーを 1 つの論理サーバーとして結びます。ノード A で発行されたメッセージはノード B に接続している購読者にも届き、プレゼンスはローカルノードだけでなくクラスター全体の名簿を返します。バックプレーンは 2 種類あります。ノード同士が直接通信し、追加のインストールが不要な組み込みメッシュと、より大規模な配備向けの Redis Pub/Sub (Enterprise) です。
uses
sgcWebSocket, sgcWebSocket_Protocols, sgcWebSocket_Cluster;
oCluster := TsgcWSCluster.Create(nil);
oCluster.EngineType := clusterMesh; // no extra infrastructure
oCluster.ClusterPort := 5410; // this node's mesh listener
oCluster.Peers.Add('192.168.1.101:5410'); // the other nodes
oCluster.Attach(oProtocol); // cluster this protocol's pub/sub
oCluster.Start;
詳細はこちら: WebSocket サーバーを複数ノードにスケールする。
メッセージ履歴と再接続リカバリー
sgc プロトコルのサーバーは、各チャンネルの直近 N 件のメッセージを、必要なら生存期間付きで保持できるようになりました。クライアントが再接続して再購読するとき、実際に受け取った最後のメッセージのオフセットを送ると、サーバーは離席中に発行されたものをすべて再生します。すでに行っている再購読以外、クライアントコードに変更はありません。そして、この仕組み全体は有効にしない限りオフのままです。
oProtocol.History.Enabled := True;
oProtocol.History.Size := 1000; // last 1000 messages per channel
oProtocol.History.TTLSeconds := 3600; // optional: also expire after 1 hour
詳細はこちら: メッセージ履歴と再接続リカバリー。
async / await と、本当に待つ Connect
新しい sgcBase_AsyncAwait ユニットは、タスクとフューチャーをライブラリにもたらします。イベントハンドラーを 1 つも書かずに HTTP リクエスト、WebSocket 接続、AI のチャット補完を await でき、結果を ThenProc と OnError で連鎖させ、内部のリクエストを実際に中断する形でタスクをキャンセルできます。
同じ発想で、Connect は接続が開始されただけの状態ではなく、完全に確立されるまでブロックするようになり、Disconnect はソケットが本当に閉じるまで待ちます。これにより、素早い再接続のときに悩まされていた競合状態が解消されます。接続や送信が失敗した場合、その理由は新しい LastError プロパティで取得できます。また、エラー文字列を直接返す Connect のオーバーロードもあるので、OnError を購読しなくても失敗を診断できます。
var
vError: string;
begin
if sgcWebSocketClient1.Connect(10000) then
sgcWebSocketClient1.WriteData('hello')
else
ShowMessage('Connect failed: ' + sgcWebSocketClient1.LastError);
// or get the reason back directly from the call
if not sgcWebSocketClient1.Connect(vError, 10000) then
ShowMessage('Connect failed: ' + vError);
end;
詳細はこちら: Delphi の async / await。
HTTP クライアントの堅牢化
トークンを失うもっとも簡単な方法はリダイレクトです。認証済みのリクエストに対してサーバーが別のホストへの 302 を返すと、クライアントは Authorization ヘッダーと Cookie ヘッダーを平然とそこへ再送します。2026.7 では、クロスサイトのリダイレクトでそれらを削除する StripAuthOnCrossHostRedirect と、HTTPS から平文の HTTP へダウングレードするリダイレクトを拒否する NoInsecureRedirect が追加されました。
レスポンスにも上限を設けられます。チャンク応答の 1 つの断片には MaxChunkSize、全体には MaxResponseSize です。RejectPublicSuffixCookies は、"com" や "co.uk" のように広すぎるドメインを主張する Cookie を破棄します。アップロード向けには、大きなボディを送る前にサーバーの許可を求める Expect: 100-continue と、サイズがまだ分からないアップロードをストリーミングするためのチャンク化されたリクエストボディがあります。
oHTTP.StripAuthOnCrossHostRedirect := True;
oHTTP.NoInsecureRedirect := True;
oHTTP.MaxResponseSize := 10 * 1024 * 1024; // 10 MB, 0 = unlimited
oHTTP.MaxChunkSize := 1024 * 1024; // 1 MB per chunk
oHTTP.RejectPublicSuffixCookies := True;
これらのスイッチはすべて既定でオフで、どれも低レベルの HTTP オブジェクトを触る必要はありません。既製の API クライアント (AI/LLM、仮想通貨取引所、OAuth2、Google Cloud、WhatsApp、AWS SQS、WebPush) にも公開されています。リダイレクトとサイズの防御は HTTP/2 クライアントにもあり、HTTP/3 にはレスポンスサイズの上限が加わりました。詳細はこちら: HTTP クライアントの堅牢化。
リトライ、バックオフ、ジッター
WatchDog はこれまで固定間隔で再接続していました。つまり、サーバーを見失った 1000 台のクライアントが、まったく同じ瞬間に一斉に戻ってくるということです。今回から、乗数、上限、ランダムなジッターを伴う指数バックオフをサポートするようになり、クライアント群は自然に分散します。既定は引き続き固定間隔なので、指定するまでは何も変わりません。
HTTP クライアントも独自のリトライポリシーを備えました。設定可能なステータスコードのリストでリトライし、毎回待ち時間を延ばし、サーバーが Retry-After のヒントを送ってきたときはそれに従います。OpenAI、Anthropic、Gemini の各クライアントもこれを利用します。
sgcWebSocketClient1.WatchDog.Backoff := wdbExponential;
sgcWebSocketClient1.WatchDog.BackoffMultiplier := 2.0; // double every attempt
sgcWebSocketClient1.WatchDog.MaxInterval := 60; // seconds, the ceiling
sgcWebSocketClient1.WatchDog.Jitter := 0.2; // up to 20% random spread
詳細はこちら: 指数バックオフ、ジッター、Retry-After。
送信キューのバックプレッシャー
クライアントが書き込みより遅く読み取ると、キューに入ったメッセージがサーバーのメモリに積み上がります。これからは QueueOptions.MaxQueueSize で接続ごとの保留メッセージ数に上限を設け、上限に達したときの動作を選べます。もっとも古いメッセージを捨てる、もっとも新しいものを捨てる、あるいは接続を切断する、のいずれかです。新しい OnSendBufferFull イベントは何かが破棄される前に発火するので、ログに残す、カウントする、あるいは切り詰められては困る接続については破棄を拒否する、といったことができます。キューは既定では無制限です。
oServer.QueueOptions.MaxQueueSize := 1000;
oServer.QueueOptions.OverflowPolicy := qopDropOldest; // or qopDropNewest, qopDisconnect
詳細はこちら: 遅い WebSocket クライアントのための送信キュー制限。
HTTP サーバーの gzip と deflate
HTTP サーバーは、クライアントが Accept-Encoding を提示したときに応答を圧縮できるようになりました。DocumentRoot から配信されるファイルにも、OnCommandGet で自分で組み立てる応答にも適用されます。最小サイズ未満のボディや、圧縮しても小さくならないコンテンツタイプはスキップされ、HTTP.sys サーバーでも利用できます。圧縮は既定でオフで、現時点では HTTP/1.1 の応答のみが圧縮されます。
sgcWebSocketHTTPServer1.HTTPCompression.Enabled := True;
sgcWebSocketHTTPServer1.HTTPCompression.Level := 6; // 1..9
sgcWebSocketHTTPServer1.HTTPCompression.MinSize := 1024; // bytes
詳細はこちら: HTTP サーバーの gzip と deflate 圧縮。
HTTP QUERY メソッド
QUERY は新しい IETF の HTTP メソッドで、POST のように検索条件をリクエストボディで送りながら、GET のように安全でキャッシュ可能なままです。つまり、クエリを長さ制限のある URL に押し込む必要がなくなります。2026.7 は HTTP/1.x、HTTP/2、HTTP/3、REST の各クライアントで実装し、サーバーとプロキシもこれを処理します。
vResult := oClient.Query('https://api.example.org/contacts', oQuery);
詳細はこちら: Delphi の新しい HTTP QUERY メソッド。
E2EE の ID 検証
エンドツーエンド暗号化はペイロードを秘匿しますが、それだけでは相手が誰なのかは分かりません。中間にいるサーバーやリレーが、双方にそれぞれ自分の鍵を渡してすべてを読むことができてしまいます。2026.7 では、各側が長期の ID 鍵で自分の暗号鍵に署名し、相手側がその署名を検証できます。これにより、こっそりとした鍵のすり替えは受け入れられるのではなく検出されます。
これは 1 対 1 でもグループチャットでも機能し、ピアの ID を承認またはピン留めするイベントや、ピアの ID 鍵が変わったときに警告するイベントを追加します。既定ではオフで、2026.6 のピアとの後方互換性も完全に保たれます。
E2EE.E2EE_Options.Identity.Enabled := True;
E2EE.E2EE_Options.Identity.PrivateKey := LoadIdentityPrivateKey; // PEM
E2EE.E2EE_Options.Identity.PublicKey := LoadIdentityPublicKey; // PEM
E2EE.OnE2EEVerifyPeerIdentity := OnE2EEVerifyPeerIdentityEvent;
E2EE.OnE2EEKeyChange := OnE2EEKeyChangeEvent;
詳細はこちら: E2EE の ID 検証。
MCP クライアントの OAuth2 と Identity Assertion グラント
MCP クライアントは、静的な API キーの代わりに OAuth2 で認証できるようになりました。トークンを自分で取得し、有効期限が切れるまでキャッシュして更新します。OAuth2 が有効なときは API キーより優先されます。あわせて、OAuth2 クライアントに新しいグラントタイプ、Identity Assertion Authorization Grant が加わりました。これはあるドメインの ID を別のドメインへ連鎖させるもので、クライアントが複数ステップの交換全体を代行し、各ステップを追えるようにイベントを発生させます。
MCPClient.MCPOptions.AuthenticationOptions.OAuth2.Enabled := True;
MCPClient.MCPOptions.AuthenticationOptions.OAuth2.GrantType := auth2ClientCredentials;
MCPClient.MCPOptions.AuthenticationOptions.OAuth2.TokenURL := 'https://auth.example.com/oauth2/token';
MCPClient.MCPOptions.AuthenticationOptions.OAuth2.ClientId := 'YOUR_CLIENT_ID';
MCPClient.MCPOptions.AuthenticationOptions.OAuth2.ClientSecret := 'YOUR_CLIENT_SECRET';
詳細はこちら: MCP クライアントの OAuth2。
仮想通貨フィード: 再購読とレート制限
これまで、マーケットデータのソケットが切れて WatchDog がそれを復旧させたとき、ソケットは上がっていても、すべての購読を自分で再生するまでは何も購読していない状態でした。取引所クライアントが、それを代わりに行えるようになりました。Resubscribe := True と設定すれば、再接続後にストリームが復元されます。対象は Binance、Kraken、Coinbase とほかの 14 ほどの取引所、それに XTB のセッションベースのフィードです。既定は False です。
REST API クライアントには、オプションのクライアント側レートリミッターが加わりました。これにより、リクエストのバーストで取引所から一時的に BAN されることがなくなります。一定時間内に送信するリクエスト数に上限を設け、超過したリクエストを待たせるか拒否するかを選べます。既定はオフです。
oBinance.RateLimit.Enabled := True;
oBinance.RateLimit.IntervalMs := 60000; // one minute window
oBinance.RateLimit.MaxRequests := 1000;
oBinance.RateLimit.Behavior := rlbWait;
詳細はこちら: 再購読とクライアント側レートリミッター。
細かな追加
- TLS プリセット。 すべての TLS オプションオブジェクトが
Presetプロパティを公開するようになりました。TLSOptions.Preset := tlspSecureDefaultsと設定すれば、証明書の検証、TLS 1.2 以上、ホスト名チェックが 1 行で有効になります。既定のtlspCustomは、現在の設定をそのまま維持します。 - カスタム HTTP セッションクラス。
TIdHTTPSessionの独自の派生クラスを、起動前に HTTP サーバーのSessionClassに割り当てれば、セッションの中に独自のデータを保存できます。セッション ID、Cookie、タイムアウト、クリーンアップはこれまでとまったく同じように動作します。セッションの保存場所まで完全に制御したい場合は、独自のSessionListを割り当てることもできます。 - RFC 2253 の証明書ヘルパー。 証明書のサブジェクトと発行者を、標準的な RFC 2253 の識別名文字列として読み取る関数が追加されました。
- WinHTTP WebSocket クライアント。 標準クライアントと同様にトークン/ベアラーおよび URL によるログインをサポートし、接続リクエストに独自のヘッダーを追加できるよう
OnHandshakeイベントを公開し、接続、切断、送受信したすべてのテキストおよびバイナリメッセージを記録するログファイルを書き出せるようになりました。OAuth2、JWT、セッションによるログインは引き続き利用できません。Windows 組み込みのネットワークスタックを使用しており、Indy を含まないためです。
修正と堅牢化
2026.7 には長い修正リストが含まれます。すべてを繰り返すのではなく、その総体として何が得られるのかをまとめます。
メモリ安全性とパーサーの堅牢化。 バッファ末尾を越える読み取りを、MQTT 5 クライアント (実際に送った以上のデータを主張するブローカー)、AMQP 1.0 クライアント (UUID のデコード)、STUN/TURN パーサー (無限ループと IPv6 アドレスを含む)、WebRTC の SCTP データチャンネル、生 TCP のフレームスキャナーで修正しました。UDP クライアントとサーバーは、DTLS を含め、切断時にソケットを二重に解放したり、ダングリングのまま残したりしなくなりました。行儀の悪いピアがメモリを無制限に増大させられる箇所には、内部的な上限を追加しました。MQTT の保留メッセージキュー、sgc プロトコルの接続ごとの購読、WAMP サーバーの保留中の呼び出し、チャンク応答のトレーラー行、AMQP フィールドテーブルのネスト深度です。
HTTP/2。 展開後サイズの上限 (既定 64 MB) により、「zip bomb」応答によるメモリ枯渇の穴をふさぎました。レスポンスサイズの制限は、応答の最後の部分によって回避されることがなくなり、失敗したリクエストはタイムアウトを待ち切るのではなく、ただちに失敗するようになりました。
暗号と乱数。 WebAuthn サーバー、OAuth2 認可サーバー、組み込みの HTTP セッション ID は、暗号学的に安全な乱数生成器を使うようになり、チャレンジは 1 回限りの使用となり、シークレットは定数時間で比較されます (クライアントシークレット、JWT 署名、HTTP API の Basic パスワード)。署名は正しいがクレームが不正な JWT は、受け入れられるのではなく拒否されるようになりました。OpenSSL の StrictVerify を有効にすると、証明書はホスト名に対しても検証されるため、別のホスト向けに発行された有効な証明書は拒否されます。IP アドレスへの接続と既存の設定には影響しません。
Server-Sent Events。 1 回の読み取りで複数のイベントが届いたストリーミング応答や、2 回の読み取りにまたがって分割されたイベントで、最初の 1 件を除いてすべてが失われていました。これを修正し、AI/LLM クライアントのトークン単位のストリーミングが復活しました。OpenAI のストリーミングチャットも stream フラグを設定できていなかったため、ほかのプロバイダーと同じようにストリーミングするようになりました。
取引所クライアント。 Kraken のリクエスト ID は厳密に増加するようになり、BitMEX は有効期限をミリ秒ではなく秒で送るようになり、MEXC は実際に送信するエンコード済みパラメーターに署名するようになり、Cryptorobotics は by-hash 呼び出しで 2 つの値を取り違えなくなり、Deribit はログイントークンを期限切れ前に更新するようになり、Forex クライアントはアカウント ID の読み取り中に握りつぶしていたエラーを報告するようになりました。
Lazarus と Free Pascal。 コンパイルに関する 3 つの修正です。JSON ユニットのインターフェイスがプラットフォームごとに正しい呼び出し規約を使うようになり (Linux でコンパイルに失敗していました)、Forex クライアントは数値書式を読むために Delphi 専用の関数を呼ばなくなり、耐量子鍵交換のユニットは size_t に依存しなくなりました。
ほかにも history.txt に多数の項目があります。gRPC クライアント (並行呼び出しで互いの応答を受け取ることがあり、送信の失敗が成功として報告されていました)、OpenAPI サーバー (仕様の読み込みがスレッドセーフになり、内部ロックを保持したままハンドラーが実行されることがなくなりました)、ログイン失敗のたびに発生していたサーバー接続とソケットのリーク、Ollama や LM Studio のように "message" フィールドを持たない OpenAI 応答でのクラッシュ、WinHTTP クライアントの WriteAndWaitData の修正、そして HTTP クライアントのログでのシークレットの秘匿 (ログを有効にしてもトークンが平文でディスクに書き込まれなくなりました) などです。
.NET エディション
sgcWebSockets .NET 2026.7 は HTTP クライアントに注力しています。Delphi 版と同じ一連の防御を搭載します。クロスサイトのリダイレクトでの資格情報の削除、HTTPS から HTTP へのダウングレードのブロック、チャンクごとおよび合計のレスポンスサイズ上限、パブリックサフィックス Cookie の拒否、Expect: 100-continue、チャンク化されたリクエストボディです。これらは HTTP クライアントコンポーネントと既製の API クライアント (AI/LLM クライアント、OAuth2、Google Cloud、WhatsApp、AWS SQS、WebPush) で利用でき、同じリダイレクトとサイズの防御は HTTP/2 クライアントにもあります。リダイレクト処理と Cookie の有効期限の修正も含まれています。すべて既定でオフです。
アップグレード
2026.7 は既存の 2026.x プロジェクトへそのまま差し替えられるアップグレードです。このリリースの新機能はすべて既定でオフです。クラスタリング、メッセージ履歴、バックオフ、送信キューの上限、HTTP 圧縮、クライアントの防御機能、E2EE の ID 検証、取引所の再購読は、いずれも明示的に有効にする必要があるため、新しいビルドをインストールしても、オプトインするまで動作は変わりません。
有効なサブスクリプションをお持ちのお客様は、カスタマーエリア、または esegece.com/products/websockets/download から新しいビルドをダウンロードできます。
ご質問、フィードバック、移行のお手伝いが必要ですか。お問い合わせください。コードを書いた本人から返信が届きます。
