sgcWebSockets 2026.10 发布了。这个版本贯穿着三条主线:sgcHTML 补齐了一个商业级 Web 应用需要的部分,让你不用再手写这些代码;密码学也在没有引入任何一个外部库的情况下迈向了后量子时代;而一组全新的 Enterprise 认证组件接管了登录界面。
Web 应用:繁琐的部分,搞定了
会话、登录与 CSRF。新的 TsgcHTMLAuth 组件及其会话存储负责维护 cookie、响应登录和登出请求、关闭空闲会话,并对失败的登录进行限流。CSRF 令牌放在一个 meta 标签里,htmx 会自动把它加到每个请求上,服务器则会拒绝不携带它的 post 请求。
FAuth := TsgcHTMLAuth.Create(Self);
FAuth.SessionStore := TsgcHTMLSessionStore_Memory.Create(Self);
FAuth.CookieName := 'app_session';
FEngine.Auth := FAuth;
读起来就像路由的路由。路径参数、方法过滤器,以及对请求头、cookie 和请求体的访问:
with FRouter.Routes.Add do
begin
Path := '/customers/{id}/edit';
Methods := [hrmGet, hrmPost];
RequireLogin := True;
RequireRoles := 'admin,sales';
end;
可以测试的页面。DispatchDirect 可以在没有底层 socket 的情况下应答一个请求,一个新的单元会读取生成的 HTML,按 id、类、标签或属性查找元素,并把一个页面与保存的副本进行比较,这样标记中一次无意的改动会被测试发现,而不是被客户发现。
感觉像原生应用的导航。页面切换不需要完全重新加载,并会保留滚动位置和用户正在输入的内容,还带有加载进度条、连接断开时的提示框,以及请求失败时的消息。所有这些功能默认都是关闭的。
四个重点新功能
每一项都有单独的文章介绍,链接在文末,这里只说它是什么:
- MCP Apps。一个用页面而不是段落来应答的 MCP 工具,可以在 ChatGPT、Claude 或 VS Code 中渲染,由和其他 sgcHTML 页面相同的组件构建而成。
- AI 页面生成器。描述一个页面,或者给设计器一张截图,它就会用你已注册的组件把页面构建出来,作为一个你可以接受或放弃的候选方案。
- CRUD 组件。列表、搜索、分页、表单、删除,以及一个数据集的写入路径,可以基于 TDataSet,也可以基于你自己的 SQL,并配有 IDE 向导和命令行生成器。
- AI Data Pack。用自然语言向一个 grid、一个数据表或一个数据透视表提问,内置的基于规则的解析器在完全没有 API key 的情况下也能作答。
推送,两种方式
服务器发送事件(server sent events)现在可以取代 WebSocket 来传送更新,并能在断线期间重放错过的内容,而且它可以配合普通的 HTTP 服务器工作。Web Push 则可以触达一个已经关闭的浏览器。它们还带来了一个通知收件箱和一个偏好设置表,通知组件会决定某个用户走哪条通道。
面向 Delphi 的 EventSource 客户端
全新的 TsgcSSEClient 可消费任意 Server-Sent Events 流,并在所有版本中提供。它会自行重新连接并发送 Last-Event-ID,让服务器从流中断的位置继续。服务器发送的 retry: 字段会被遵循,OnEvent 会把事件类型、数据和 id 交给您,ReconnectOptions 则加入了退避和抖动。TLS、代理和身份验证在 OnBeforeConnect 中设置,该回调会把组件所使用的 HTTP 客户端交给您。
FSSE := TsgcSSEClient.Create(Self);
FSSE.URL := 'https://example.com/events';
FSSE.ReconnectOptions.Backoff := True;
FSSE.ReconnectOptions.MaxInterval := 30000;
FSSE.ReconnectOptions.Jitter := 0.2;
FSSE.OnEvent := DoSSEEvent;
FSSE.Open;
procedure TForm1.DoSSEEvent(Sender: TObject; const aEvent: TsgcSSEEvent);
begin
Memo1.Lines.Add(aEvent.EventType + ': ' + aEvent.Data);
end;
它背后的解析器 TsgcSSEParser 是公开的。把任意 text/event-stream 的字节以任意大小的分块喂给它即可,而这正是 LLM 流式响应或 MCP Streamable HTTP 响应的样子。
FParser := TsgcSSEParser.Create;
FParser.OnEvent := DoSSEEvent;
FParser.Feed('event: delta' + #10 + 'data: {"text":"Hel"}' + #10#10);
新增的演示 Demos\20.HTTP_Protocol\17.SSE_Client_Component 完整展示了整个流程。
AI:可以直接拿来用的答案
TsgcAIChat 现在可以通过新的 ChatJSON 方法,在 OpenAI、Anthropic、Gemini、DeepSeek、Ollama、Grok 和 Mistral 上请求遵循你提供的 schema 的 JSON;该方法会解析返回结果,当解析失败时会附上解析错误再问一次。聊天组件现在也能发送和接收图片了,而且 BaseUrl 现在对每个提供商都生效,而不再只对 Ollama 生效,这样它们中的任何一个都可以指向一个代理或本地网关。
文档提取:从 PDF 到经过校验的 JSON
新增的 TsgcAIDocumentExtractor 接收一个 PDF 或图片以及一个 JSON schema,返回按该 schema 校验过的 JSON。OpenAI、Anthropic 和 Gemini 直接读取 PDF,其他视觉模型读取图片。内置预设覆盖发票、收据和身份证件(dpInvoice、dpReceipt、dpIDCard),每个字段都带有置信度,因此 OnLowConfidence 会告诉您哪些低于 MinConfidence 的值值得再核实一遍。当答案未通过校验时,组件会带着错误信息再问一次(ValidationRetries)。
FExtractor := TsgcAIDocumentExtractor.Create(Self);
FExtractor.AIChat := AIChat1;
FExtractor.Preset := dpInvoice;
FExtractor.MinConfidence := 0.8;
FExtractor.OnLowConfidence := DoLowConfidence;
Memo1.Lines.Text := FExtractor.ExtractFile('invoice.pdf');
if FExtractor.LastResult.FieldConfidence('total') < 0.8 then
ShowMessage('Check the total by hand');
关联一个 TsgcAIOCRTesseract,或者关联使用 Windows 10 及更高版本内置 OCR、无需安装任何东西的 TsgcAIOCRWindows,并把 OCRMode 设为 domFallback 或 domAlways,文本就会先在本地被识别,这样即使是运行在 Ollama 上的纯文本模型也能完成提取。若要使用自己的提示词,TsgcAIChat 新增了 ChatWithDocument、ChatWithDocumentBase64、ChatWithAttachments 和 ChatJSONWithAttachments,它们会随消息发送一个或多个文件,这些文件保存在 TsgcAIChatAttachments 列表中。
一个会听、会说、还会调用工具的语音代理
全新的 TsgcAIVoiceAgent 是一个组件,它能倾听、检测用户何时说完一轮、用自己的声音回答并调用您的工具,通过 OpenAI Realtime 或 Gemini Live 实现。它使用 WebSocket 通信,或者与 OpenAI 之间使用 WebRTC,并可在 Windows、Android 和 iOS 上运行。轮次检测支持服务器端 VAD、语义 VAD、客户端 VAD 或手动方式(vtdServerVAD、vtdSemanticVAD、vtdClientVAD、vtdManual)。通过 BargeIn,用户可以打断,代理会停止说话,并在被打断处截断其回答。OnTranscript 会提供用户和代理双方的实时转写。
FAgent := TsgcAIVoiceAgent.Create(Self);
FAgent.Provider := vapOpenAI;
FAgent.OpenAIOptions.ApiKey := 'sk-...';
FAgent.Instructions := 'You are the shop assistant. Keep answers short.';
FAgent.TurnDetection.Mode := vtdSemanticVAD;
FAgent.BargeIn := True;
oTool := FAgent.Tools.Add;
oTool.Name := 'find_product';
oTool.Description := 'Looks up a product by name';
oTool.Parameters :=
'{"type":"object","properties":{"name":{"type":"string"}}}';
FAgent.OnTranscript := DoTranscript;
FAgent.OnToolCall := DoToolCall;
FAgent.Start;
procedure TForm1.DoToolCall(Sender: TObject; const aCallId, aName,
aArguments: string; var aResult: string; var aHandled: Boolean);
begin
if aName = 'find_product' then
begin
aResult := FindProduct(aArguments);
aHandled := True;
end;
end;
工具来自 OnToolCall,当一个 TsgcWSAPI_Client_MCP 被赋值给 MCPClient 时,该 MCP 服务器的工具会自动提供给模型。对于电话场景,Audio.Format 会切换到 8 kHz 的 G.711 mu-law 或 A-law(vafG711ULaw、vafG711ALaw)。该语音代理适用于 Delphi 7 到 Delphi 13 以及 .NET,新增的演示把它变成了一个基于 TDataSet 的语音商店助手。
密码学:用 Object Pascal 实现的后量子能力
ML-KEM(FIPS 203)、ML-DSA(FIPS 204)和 SLH-DSA(FIPS 205)、X-Wing 混合密钥封装、后量子 X.509 证书与证书颁发机构,以及用 ML-DSA 签名的 JWT。这一切都用 Object Pascal 写在 sgcCrypto 包里,不依赖任何外部库,并针对 NIST 的已知答案向量做了验证。
在此之上是一个原生 TLS 1.3 和 TLS 1.2 引擎,同样是纯 Pascal 实现:客户端或服务器无需 OpenSSL、也无需 SChannel 就能进行 TLS 通信,协商 RFC 10024 中的混合后量子分组,并支持 ALPN、S N I、客户端证书,以及可选地使用操作系统的信任存储。TLS 1.2 是为那些还无法使用 TLS 1.3 的对端准备的,默认提供具有前向保密性的 AES-GCM 和 ChaCha20-Poly1305 套件、扩展主密钥和降级保护,TLSOptions.Version 用于设置允许的最低版本。混合分组仍然只存在于 TLS 1.3 中。
经典算法也在同一轮改动中得到了加固:带盲化的常数时间 RSA、常数时间的椭圆曲线标量乘法与 Ed25519、无查找表的 AES 和 GHASH、导入的私钥会与其公钥部分做校验,以及拒绝非最小编码的 DER 签名。
认证:每个客户都在要的登录
一组全新的认证组件回答了每个客户关于登录界面的问题。它们随 Enterprise 和 All-Access 版本以及 sgcAuth 包提供,相同的组件也是 sgcWebSockets .NET 的一部分。
- Passkey。WebAuthn 服务端可以在用户不输入用户名的情况下完成登录,在浏览器自带的自动填充列表中提示 Passkey,为每个用户保留多个 Passkey,区分已同步的 Passkey 和绑定单一设备的 Passkey,并触发事件,让凭据保存在你自己的数据库里。
- SAML 单点登录。
TsgcSAMLServiceProvider让你的应用成为面向 Entra ID、Okta、AD FS、Google Workspace、Keycloak 或任何其他身份提供商的 SAML 2.0 服务提供方。 - Active Directory 与 LDAP。
TsgcLDAPClient通过 LDAPS 或 StartTLS 用目录密码验证用户,并读取其所属组,包括嵌套组。 - 身份验证器应用的验证码。
TsgcTOTPAuthenticator生成并校验 Google Authenticator、Microsoft Authenticator 等应用的验证码,包含用于二维码的注册链接、防重放保护和恢复码。 - OpenID Connect。
TsgcHTTP_OIDC_Client通过发现文档在任何 OpenID 提供商处完成登录,并验证到达你自己 API 的 ID 令牌和 bearer 令牌。 - 不保存密码的邮件。
TsgcMailOAuth2获取并刷新 SMTP、IMAP 和 POP3 如今所要求的 Microsoft 365 与 Gmail OAuth2 令牌。
值得一提的修复
- 使用 RSA 和 ECDSA 密钥进行 JWT 签名与验证时,以及在静态链接 OpenSSL 的 32 位应用中,存在的内存损坏问题。
- SChannel 处理程序在每次使用 PFX 文件建立连接时,都会在 Windows 密钥存储中留下一份私钥副本,并且在较新版本的 Windows 上不会发送客户端证书。
- 使用 Windows 存储中证书的并发 SChannel 连接握手失败。
- OAuth2 服务器会拒绝用 RSA 密钥签名的 DPoP 证明。
- CloudFront 签名 URL 的签名没有做 URL 安全编码。
.NET
.NET 库同步跟进:为 ASP.NET Core 提供 ClaimsPrincipal 桥接的身份验证与会话管理、路由器、测试辅助工具、SPA 导航、带原生端点的 SSE 传输、结构化输出、带两种 OCR 引擎的文档提取、实时语音代理、AI Data Pack、Web Push、MCP Apps、带适配器的 CRUD 组件,以及全新的 TsgcSSEClient,全部使用与 Delphi 相同的 API 名称。
面向 ASP.NET Core 的 Razor Tag Helpers。sgcHTML 现在可以像 Telerik UI 和 DevExpress 那样融入 MVC 或 Razor Pages 应用。<sgc-grid>、<sgc-form>、<sgc-autocomplete>、<sgc-dialog> 和 <sgc-chart> 等 Tag Helper,以及 Html.Sgc() 下与之对应的流式写法,会在服务器端渲染 Bootstrap 5,并通过 htmx 与您的控制器通信,无需 JavaScript 框架。网格在 IQueryable 上完成分页、排序、筛选、搜索,并可导出为 XLSX 和 PDF,因此 EF Core 会把这一切都作为 SQL 执行:
<sgc-grid name="orders" key="Id" items="Model"
asp-action="Read" asp-export-action="Export" export="xlsx,pdf"
page-size="15" sortable="true" filterable="true"
searchable="true" push-url="true">
<sgc-column field="Reference" searchable="true" />
<sgc-column field="Customer" searchable="true" />
<sgc-column field="OrderDate" title="Date" format="{0:yyyy-MM-dd}" filter="range" />
<sgc-column field="Total" format="{0:N2}" align="right" filter="range" />
</sgc-grid>
// OrdersController
public IActionResult Read(SgcDataRequest request) => this.SgcGrid(request, Rows());
输入控件通过 asp-for 绑定并显示 ModelState 错误,this.SgcCloseDialog("edit-order", refresh: "orders") 会关闭编辑对话框并重新加载网格。其他产品所没有的是服务器推送:当后台服务调用 hub.BroadcastChartAsync(...) 时,带有 live="true" 的图表会在每个打开的浏览器中重绘,通过 sgcHTML WebSocket 完成,无需任何 SignalR 代码。它包含在 esegece.sgcHTML.AspNetCore NuGet 包中,Community 版同样可用,22.RazorMvc 演示就是用它重建的、大家熟悉的订单示例。
升级
所有新增功能都是增量式的,并且默认关闭。加入新的单元、重新编译你的包,现有应用的行为将与之前完全一致。
完整版文章
- 在 ChatGPT 和 Claude 中运行你的 Delphi 应用
- 把一张截图变成一个 Delphi 网页
- 不依赖 OpenSSL DLL 的 Delphi TLS 1.3
- 五分钟构建一个 Delphi Web CRUD 页面
- 用简单英语向你的 Delphi 表格提问
- 从 Delphi 触达一个已经关闭的浏览器
- Passkey、SAML SSO、LDAP 与 TOTP 双因子认证:Delphi 登录组件
- 在 Delphi 中通过 Entra ID、Okta 和 AD FS 实现 SAML 单点登录
观看视频
关于此功能的简短视频发布在eSeGeCe 频道上。
有问题、反馈,或需要迁移方面的帮助?欢迎联系我们 — 你会收到编写这些代码的人的回复。
