Delphi 中的实时通信——选择您的协议

WebSocket、Server-Sent Events、HTTP/2 服务器推送、MQTT、AMQP 和 WebRTC 都解决"发生事件时推送客户端"的问题。它们的运营特性截然不同——本页是选择正确协议的小抄。

一个库,六种实时协议

sgcWebSockets 在包内提供每个主流的 Delphi 实时客户端和服务器——因此问题不再是"我可以在 Pascal 中做到这一点吗?",而变成"哪种协议适合这项工作?"

"Delphi 中的实时通信"是一个伞形术语——实际上它涵盖了六种根本不同的网络原语,每种都有不同的延迟、顺序、扇出、NAT 穿越和基础设施特性。错误选择会浪费数月:您交付了一个轮询 REST 循环,遇到可扩展性瓶颈,改装 WebSocket 层,然后发现 MQTT 本应是更好的选择,因为您的流量本质上是发布/订阅。本页是简短而有主见的指南。

用一张表选择协议

扫描各行;绿色最多的那一列胜出。

需求 WebSocket SSE HTTP/2 推送 MQTT AMQP WebRTC
双向否(仅服务器→客户端)是(发布/订阅)是(发布/订阅)是(对等)
扇出广播服务器实现仅按客户端仅按流原生(主题)原生(交换机)否(1:1)
浏览器支持通过 WebSocket通过 WebSocket
通过企业代理通过 wss://443是(看起来像 HTTP)通过 WSS通过 WSS通常(TURN)
保证投递应用级应用级应用级QoS 1/2已确认SCTP 可靠
低带宽设备中等中等极佳中等中等
P2P / NAT 穿越否(服务器)否(代理)否(代理)是(ICE)
端到端加密TLS 逐跳TLS 逐跳TLS 逐跳TLS 逐跳TLS 逐跳DTLS-SRTP 端到端
服务器可在 Delphi 中运行使用外部代理使用外部代理是(信令 + STUN/TURN)

简短版

WebSocket

默认选择。双向、开销低、在每个浏览器中工作。适用于实时仪表板、聊天、协作编辑、自定义应用协议。组件 →

Server-Sent Events

当流量是仅服务器 → 客户端且您希望最简单的模型时选择:一个流式传输文本的长期 HTTP 响应。每个浏览器中内置,无需库。SSE →

HTTP/2 推送

用于与主文档一起主动发送子资源(CSS、JS、JSON)——节省一次往返。不是通用的"推送"通道。HTTP/2 →

MQTT

面向 IoT、遥测、移动状态、联网车辆的发布/订阅。QoS 1/2、保留消息、遗嘱、极小的线开销。需要代理。MQTT →

AMQP

企业消息:持久队列、交换机、路由键、死信处理、RabbitMQ / Azure Service Bus / IBM MQ。当您需要丰富路由时选择,而非 MQTT。AMQP →

WebRTC

带 NAT 穿越的直接点对点——用于协作的数据通道,最终是音频/视频。E2E 加密 P2P 的唯一选择。WebRTC →

每个看起来是什么样的

使用每个协议进行连接的最小可行 Delphi 代码片段——相同的库,相同的组件模式。

WebSocket

WS := TsgcWebSocketClient.Create(nil);
WS.URL := 'wss://echo.websocket.events';
WS.OnMessage := DoMessage;
WS.Active := True;
WS.WriteData('hello');

Server-Sent Events

SSE := TsgcWSPClient_SSE.Create(nil);
SSE.URL := 'https://stream.example.com/events';
SSE.OnEvent := DoEvent;
SSE.Active := True;

MQTT

MQTT := TsgcWSPClient_MQTT.Create(nil);
MQTT.Client := WSClient;
MQTT.OnMQTTPublish := DoMqttPublish;
WSClient.Active := True;
MQTT.Subscribe('sensors/+/temperature', mtqsAtLeastOnce);

AMQP

AMQP := TsgcWSPClient_AMQP.Create(nil);
AMQP.Client := WSClient;
AMQP.OnAMQPMessage := DoAmqpMessage;
WSClient.Active := True;
AMQP.Consume('orders');

HTTP/2 多路复用 GET

H2 := TsgcHTTP2Client.Create(nil);
H2.Host := 'api.example.com';
H2.Port := 443;
H2.TLS  := True;
H2.OnResponse := DoResponse;
H2.Connect;
for i := 1 to 10 do H2.Get(Format('/items/%d', [i]));

WebRTC 数据通道

RTC := TsgcWSPClient_WebRTC.Create(nil);
RTC.Client := WSSignal;
RTC.IceServers.Add.URL := 'stun:stun.l.google.com:19302';
RTC.OnDataChannelMessage := DoP2PMessage;
WSSignal.Active := True;
RTC.CreateDataChannel('chat', True, True);
RTC.CreateOffer;

三个值得避免的错误

在循环中轮询 REST

如果您发现自己每两秒调用一次 Get 并对响应进行差异比较,答案几乎总是 SSE(仅服务器→客户端)或 WebSocket(双向)。CPU 和带宽节省通常达到 95 %+。

MQTT 适合时选择 WebSocket

如果您的流量本质上是基于主题的扇出(设备发布遥测、仪表板订阅),运行自定义 JSON-over-WebSocket 协议是糟糕地重新实现 MQTT。请使用代理。

将 HTTP/2 推送与服务器推送混淆

HTTP/2 push promise 是一种子资源优化,不是通用推送通道。对于长期的服务器到客户端流,您仍然需要 SSE、WebSocket 或 MQTT。

探索每个协议

Delphi MQTT 客户端

IoT 和遥测发布/订阅。

Delphi HTTP/2 客户端

多路复用 HTTP 和推送。

Delphi WebRTC 库

点对点数据通道。

Server-Sent Events

简单的服务器→客户端流式传输。

AMQP

通过 RabbitMQ、Service Bus、IBM MQ 的企业消息。

博客:SSE 客户端演练

实用的 SSE 示例。

博客:实时负载均衡

如何在 WebSocket 和 HTTP/2 前面放置 nginx / Envoy / ALB。

通过一个安装程序尝试每个协议

下载试用版——WebSocket、SSE、MQTT、AMQP、HTTP/2 和 WebRTC 的演示都在包内发布。