sgcWebSockets 2026.5는 알찬 릴리스입니다. 세 가지 새로운 인프라 구성 요소가 WebSocket / HTTP 서버를 프로덕션 등급의 API 게이트웨이로 변모시킵니다. 완전한 기능의 속도 제한기, 클라이언트 측 서킷 브레이커, 그리고 전체 라이프사이클을 지원하는 API 키 관리자가 그것입니다. 프로토콜 측면에서는 일반 Lightstreamer TLCP 2.5 구현 위에 구축된 새로운 Forex.com 클라이언트가 있고, MCP Server는 claude.ai와 같은 브라우저 기반 MCP 클라이언트에 직접 연결할 수 있도록 기본 제공 OAuth 2.1 흐름을 얻었으며, 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+에서는 한 줄짜리 래퍼도 사용할 수 있습니다. 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 + 스트리밍 액세스(로그인, 핑, 시장 감시, 포지션, 주문, 거래 내역, 거래 시뮬레이션)를 제공합니다. 이는 create_session, bind_session, control(구독 / 구독 해제) 및 재연결 후 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에 있습니다 — 로그인, 연결성 핑, 실시간 시장 감시, 포지션, 활성 주문, 거래 내역, 손절 / 한도 내역 및 거래 시뮬레이션을 제공하며, 자격 증명은 sgcForexDemo.ini에 유지됩니다.
MCP Server — 브라우저 기반 MCP 클라이언트용 OAuth 2.1
이제 MCP Server는 외부 권한 부여 서버 없이 브라우저 기반 MCP 커넥터(예: claude.ai)와 직접 통신할 수 있습니다. MCP 브라우저 커넥터 사양에 필요한 네 가지 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를 반환하고, 모든 응답에는 요청 origin을 반영하는 Access-Control-Allow-Origin과 Strict-Transport-Security: max-age=31536000 HSTS 헤더가 포함됩니다.
IOCP 및 EPOLL: 여섯 가지 튜닝 개선
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힙 폴백을 방지합니다. 루프백 벤치마크에서 +15–18% WebSocket 처리량입니다.
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— 수락 루프와 slow-loris 가드를 튜닝합니다.- EPOLLOUT 기반 쓰기 백프레셔 —
send()가 부분 쓰기에서EAGAIN을 반환하면, 나머지 바이트는 연결별 보류 버퍼에 캡처되고 소켓은EPOLLIN|EPOLLOUT으로 다시 무장됩니다. 리액터는 바이트를 삭제하거나 워커를 차단하는 대신 다음EPOLLOUT이벤트에서 꼬리를 플러시합니다.
공유
IOCP / EPOLL 워커 풀은 작업이 처리된 직후를 포함하여 모든 반복마다 sleep(1)을 호출했습니다 — 사실상 큐가 가득 차 있어도 각 워커를 ~1,000 ops/s로 제한했습니다. 이제 대기 중인 작업이 있을 때 sleep을 건너뛰어 제한이 제거되었습니다.
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는 PEM 및 원시 바이트 형식 모두로 ML-KEM-768 (FIPS 203 / Kyber-768) 키 쌍을 생성합니다. 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 Server — 누락되거나 잘못된 자격 증명은 이제
500 Internal Server Error대신 보호된 리소스 메타데이터를 가리키는WWW-Authenticate: Bearer헤더와 함께401 Unauthorized를 반환합니다. 브라우저 기반 MCP 클라이언트에 의한 OAuth 검색에 필요합니다. - MCP Server —
OPTIONS요청이 더 이상 JSON-RPC 파서에 도달하지 않습니다(이전에는500 "Invalid jsonrpc Value"를 반환했습니다). CORS 프리플라이트는 이제 인증 전에 그리고 MCP 본문 파서 전에 처리됩니다. - MCP Server — 비 ASCII 문자가 포함된 도구 설명, 프롬프트 메시지 및 리소스 콘텐츠가 더 이상 연결을 끊지 않습니다(JSON 본문이 이제 선언된
charset=utf-8과 일치합니다). - MCP Server — 비 ASCII 문자가 포함된
tool/prompt/resource/root/template/ 완료 참조 및 완료 인수name필드가 이제 원시 UTF-16 코드 포인트가 아닌 JSON\uXXXX이스케이프로 적절히 방출되고 읽힙니다. - HTTP API 요청 본문 —
TsgcWSComponent_Server.DoHTTPRequestAPI는 인코딩을 지정하지 않고ReadStringFromStream을 호출하여 ASCII로 기본 설정되고 이벤트 핸들러가 보기 전에 모든 비 ASCII 바이트를?로 대체했습니다. 수정됨. - HTTP.sys Server —
TsgcHTTPServerAPI.DoExecute의ERROR_MORE_DATA에 대한 컨텍스트 누수. 수락 루프는 이제 동일한 요청 ID에서 버퍼를 키우고HttpReceiveHttpRequest를 재시도하며 모든 오류 경로에서 고립된 컨텍스트를 해제합니다. - HTTP.sys Server —
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)에서 잘못된 포인터 작업이 발생했습니다.
업그레이드
2026.5는 기존 2026.4 프로젝트에 대한 즉시 사용 가능한 업그레이드입니다. 기존 구성 요소에 대한 인터페이스 변경은 없습니다. 새로운 속도 제한 / 서킷 브레이커 / API 키 구성 요소는 추가적이며 옵트인입니다. HTTP.sys 고성능 모드는 FineTune.OperatingMode := ompHighPerf 뒤에 게이트되어 있습니다 — 기존 코드는 클래식 경로에 머무릅니다.
활성 구독이 있는 고객은 고객 영역에서 새 빌드를 다운로드할 수 있습니다. 평가판 사용자는 esegece.com/products/sgcwebsockets/sgcwebsockets-download에서 업데이트된 설치 프로그램을 받을 수 있습니다.
질문, 피드백 또는 마이그레이션 도움이 필요하신가요? 문의하기 — 코드를 작성한 사람들로부터 직접 답변을 받게 됩니다.
