Delphi ICE 客户端
在 Delphi/C++Builder 中运行完整的 ICE 算法 — 收集主机、服务器反射和中继候选,执行 STUN 连接检查,按 RFC 8445 提名最佳候选对。
在 Delphi/C++Builder 中运行完整的 ICE 算法 — 收集主机、服务器反射和中继候选,执行 STUN 连接检查,按 RFC 8445 提名最佳候选对。
实现 RFC 8445 ICE 状态机 — 候选收集、优先级排序、候选对生成、连接检查(带 USE-CANDIDATE 的 BindingRequest)、提名和同意刷新。
配置 STUN/TURN ICE 服务器,调用 GatherCandidates,与对端带外交换候选列表,然后调用 ProcessCandidates 执行连通性检查并提名一个可用的候选对。
uses
sgcP2P, sgcP2P_ICE_Classes;
// TFormICE 持有 FClient: TsgcICEClient 和 FLog: TStringList
procedure TFormICE.Gather;
begin
FClient := TsgcICEClient.Create(nil);
FClient.ICEServers.AddURL('stun:stun.l.google.com:19302');
FClient.ICEServers.AddURL('turn:turn.example.com', 'alice', 'secret');
FClient.OnICECandidate := OnICECandidate;
FClient.OnICECandidatePairNominated := OnICECandidatePairNominated;
FClient.GatherCandidates;
end;
procedure TFormICE.OnICECandidate(Sender: TObject;
const aCandidate: TsgcICE_Candidate);
begin
// AsString 是候选行,可直接用于您的信令通道
SignalToPeer(aCandidate.AsString);
end;
// 远程候选通过您的信令通道到达
procedure TFormICE.AddRemoteCandidate(const aCandidate: string);
begin
FClient.AddRTCIceCandidate(aCandidate);
FClient.ProcessCandidates;
end;
procedure TFormICE.OnICECandidatePairNominated(Sender: TObject;
const aCandidatePair: TsgcICE_CandidatePair);
begin
FLog.Add('nominated: ' + aCandidatePair.Local.Address + ' -> ' +
aCandidatePair.Remote.Address);
end;
// includes: sgcP2P.hpp, sgcP2P_ICE_Classes.hpp
TsgcICEClient *Client = new TsgcICEClient(this);
Client->ICEServers->AddURL("stun:stun.l.google.com:19302");
Client->OnICECandidate = OnICECandidate;
Client->GatherCandidates();
可复用的 ICE 引擎,在 TsgcRTCPeerConnection 下层运行 — 或独立用于非 WebRTC 的 P2P。
并行枚举来自每个本地接口的主机候选、来自每个 STUN 服务器的服务器反射候选以及来自每个 TURN 服务器的中继候选。
按 RFC 8445 §6.1.2 计算候选对优先级并排序检查列表。冻结的候选对在其基础取得进展时解冻。
按标准发送带 PRIORITY、ICE-CONTROLLING / ICE-CONTROLLED、USE-CANDIDATE 属性的 STUN BindingRequest。触发检查在入站刺激时触发。
当某个候选对检查成功且控制代理标记 USE-CANDIDATE 时,组件会以胜出的候选对触发 OnICECandidatePairNominated,aCandidatePair.Local / Remote 则告诉您它选中了哪两个地址。
实现 RFC 7675 的同意刷新探测:每隔 ConsentInterval 毫秒在提名的候选对上发送一次 Binding 请求;若经过 ConsentTimeout 仍无响应,则以原因 Consent Freshness Timeout 触发 OnICECandidatePairFailed。
组件不假定任何特定的信令通道。您把 aCandidate.AsString 放到自己的 WebSocket、SIP 或 HTTP 信令上,再把返回的内容交给 AddRTCIceCandidate,随后调用 ProcessCandidates。