Webrtc本端和对端信令交互步骤

在官方库函数中,进入handle_signaling_message后开始解析msg消息结构体中的type,解析后会有三种type == "request",type == "answer",type == "candidate"

当对端发送 request

本端会先做四件事,这边会建立PeerConnection,创建本端DataChannel(createDataChannel(label))、添加视频轨(make_video_track(pc)),把其他的回调注册(onGatheringStateChange,onStateChange,nLocalCandidate)

后面执行c->setLocalDescription();


1. 本端 SDP

  • 库根据当前 PeerConnection 状态(已 addTrack 的视频轨、createDataChannel 的 SCTP 等)生成本地 SDP,并设为 local description。
  • 信令状态会从例如 stable → have-local-offer 一类变化(具体以 libdatachannel 为准)。

2. ICE 收集与 candidate

  • ICE gathering 会进入 InProgress,向 STUN 等发绑定请求、枚举 host / srflx 等候选。
  • 每拿到一个候选,会调注册的 onLocalCandidate → emit_signaling_json,日志输出为``type=candidate 的 TX。
  • 收集结束状态改变 GatheringState::Complete,触发 onGatheringStateChange → 取 localDescription() → emit_signaling_json 日志输出 type=offer + 整段 sdp

3. 连接状态

  • onStateChange 被调用,例如进入 Connecting( PC state=1 对应这里)
  • 等对端 answer 且本端 setRemoteDescription 成功后,才会继续到 Connected(state=2)。

4. 建立连接时刻

  • setLocalDescription() 本身不会完成对端的 setRemoteDescription,也不会立刻刻 Connected;answer 要等信令从对端来。
  • DataChannel onOpen、video track->onOpen 一般在 SDP/ICE/DTLS 更往后才触发。

5. 代码的对应关系

setLocalDescription() ------> 告诉库「按当前视频轨 && DC 配置 开始出本端 SDP 并跑 ICE」;

之后由库回调 onLocalCandidate / onGatheringStateChange 去 emit_signaling_json,把 candidate 和 offer 发到信令通道。

/创建本端 DataChannel,代码写法分析

复制代码
 std::shared_ptr<rtc::DataChannel> local_dc;   //创建本端 DataChannel
        if (cfg.enable_datachannel) {
            const std::string label = cfg.data_channel_label.empty() ? std::string("app") : cfg.data_channel_label;
            local_dc = pc->createDataChannel(label);
            attach_dc_handlers(local_dc, "local");
        }
  1. pc->createDataChannel(label)

    调用 PeerConnection 的成员函数,返回类型是 std::shared_ptr<rtc::DataChannel>(库里声明好的)

  2. local_dc

    事先声明成 同一种类型 的变量:
    std::shared_ptr<rtc::DataChannel> local_dc;

    一开始是空指针(不指向任何 DataChannel)。

  3. local_dc = ...

    这是 shared_ptr 的赋值:把函数返回的那个 shared_ptr 拷给 local_dc, local_dc 和返回值指向同一条 DataChannel 对象,引用计数按 shared_ptr 规则增加。

createDataChannel 返回 shared_ptr<DataChannel>,你用赋值运算符把它保存到 local_dc 里,后面就用 local_dc 操作这条通道。


onGatheringStateChange指针写法分析:

复制代码
 pc->onGatheringStateChange([wpc = std::weak_ptr<rtc::PeerConnection>(pc), peer_id](rtc::PeerConnection::GatheringState st) {
            if (st != rtc::PeerConnection::GatheringState::Complete) {
                return;
            }
            auto locked = wpc.lock();
            if (!locked) {
                return;
            }
            auto desc = locked->localDescription();
            if (!desc) {
                return;
            }
            json out = {{"id", peer_id}, {"type", desc->typeString()}, {"sdp", std::string(*desc)}};
            emit_signaling_json(out);
            log_info("[webrtc_ldc] sent local SDP type={}", desc->typeString());
        });
  1. pc:当前这次 request 里新建的 PeerConnection 的 shared_ptr,指向真实对象。
  2. std::weak_ptr<rtc::PeerConnection>(pc):用 pc 拷贝构造一个 weak_ptr,让 wpc 和 pc 指向同一块 PeerConnection,但 wpc 不计入引用计数。
  3. 必须传 pc:没有 shared_ptr,weak_ptr 就不知道要弱引用谁;不能凭空 weak_ptr<T>() 就绑到正确对象上。

之后回调里 wpc.lock(),等价于:"当初注册时关心的那个 PeerConnection,现在还有没有活着的shared_ptr管着它?" 有就临时拿一个shared_ptr用一下,没有就说明已经关了。

相关推荐
KING-WU5121 小时前
Linux 工具之Make 与 Makefile
java·linux·服务器
阿乔外贸日记2 小时前
全球电子产业高度集中:中、韩、日和中国台湾地区占全球数字硬件产能八成
大数据·服务器·人工智能·物联网·云计算
魔法阵维护师2 小时前
Linux 命令行入门踩坑记录:从 VMware 装系统到文件管理
linux·运维·服务器
qq_543447822 小时前
DNS解析怎么排查?故障处理与运维实用手册
运维·服务器·网络·php
DeviceHub2 小时前
AI服务器电源设计进阶:TLVR电感的应用解析与选型验证指南
运维·服务器·人工智能
Apipi*2 小时前
30天速通Linux 第七章进程间通信
linux·运维·服务器
极光通讯3 小时前
服务器内存替代料选型方法论:主料号缺货时如何找到Pin-to-Pin兼容型号
运维·服务器
草根大哥3 小时前
08-横向扩容与突发高并发:加机器到底买到了什么
运维·webrtc·srt·横向扩容·whip·自建cdn
SKH.3 小时前
Linux驱动-系统移植
linux·服务器
根目录下的猫3 小时前
虚拟机复制过来运行时:“虚拟机使用的此版本,VMware Workstation 不支持的硬件版本。”错误解决办法,亲测可用
linux·运维·服务器·后端