實現p2p的webrtc-srs版本

1. 基本知識

1.1 webrtc

一、WebRTC的本質:實時通信的“網絡協議棧”類比
將WebRTC類比為Linux網絡協議棧極具洞察力,二者在架構設計和功能定位上高度相似:

  1. 分層協議棧架構

    • Linux網絡協議棧:從底層物理層到應用層(如TCP/IP、UDP),負責數據的封裝、傳輸、路由及解析,是操作系統網絡能力的核心。
    • WebRTC協議棧
      • 傳輸層:基于UDP實現自定義數據通道(DataChannel)音視頻流傳輸,內置RTCPeerConnection處理連接建立、NAT穿越(STUN/TURN)和帶寬管理。
      • 媒體處理層:集成音視頻編解碼模塊(VP8/VP9/H.264、Opus)、前向糾錯(FEC)降噪算法等,實現低延遲媒體流的實時處理。
      • 應用層接口:通過瀏覽器API(如getUserMediaRTCPeerConnection)暴露功能,類似Linux通過Socket接口供應用調用。
  2. 原生性與系統整合

    • Linux協議棧是操作系統內核的原生組件,WebRTC則是瀏覽器內核的原生模塊(如Chrome的Blink引擎),直接調用操作系統的硬件接口(攝像頭、麥克風、網絡驅動),避免中間層性能損耗。

二、瀏覽器中的WebRTC:API接口的技術全景
WebRTC在瀏覽器中的實現,本質是將協議棧能力通過標準化API開放給開發者,其核心接口體系包括:

  1. 媒體采集與設備控制
  • getUserMedia:直接調用設備傳感器,獲取音視頻流,支持參數配置(如分辨率、幀率、攝像頭方向)。
    navigator.mediaDevices.getUserMedia({ video: { facingMode: "user" }, audio: true })  
    
  • MediaRecorder:基于WebRTC流實現客戶端錄制(如錄制會議內容)。
  1. 點對點連接建立
  • RTCPeerConnection:核心接口,負責創建連接、交換SDP信令、管理ICE候選(網絡地址),并通過addTrack/ontrack處理媒體流傳輸。
  • 信令解耦設計:瀏覽器僅處理媒體通道,信令通道需開發者自建(如WebSocket),這種分離模式與Linux協議棧“內核處理傳輸,用戶態處理應用邏輯”的設計一致。

1.2 sfu模式

SFU模式(Selective Forwarding Unit)深度解析:架構、原理與應用場景

一、SFU模式的核心定義與定位
SFU(選擇性轉發單元)是流媒體服務器的一種轉發模式,其核心功能是接收多個客戶端的媒體流,根據訂閱關系選擇性地將流轉發給其他客戶端,而非對媒體流進行解碼、混流或重新編碼。

  • 類比說明
    • 若將媒體流視為“快遞包裹”,SFU相當于快遞分揀中心
      • 包裹(原始流)到達分揀中心后,僅根據收件地址(訂閱關系)重新分揀投遞,不拆包(不解碼)、不合并包裹(不混流)。
      • 優勢在于低延遲、低計算消耗,適合實時性要求高的場景(如互動直播、視頻會議)。

二、SFU的技術架構與工作流程
1. 核心組件與網絡模型
在這里插入圖片描述

(典型SFU架構示意圖:客戶端A/B/C發布流至SFU,SFU根據訂閱關系將流轉發給訂閱者)

  • 關鍵角色

    • 發布者(Publisher):客戶端向SFU發送媒體流(如攝像頭采集的視頻流)。
    • 訂閱者(Subscriber):客戶端向SFU請求訂閱特定流,接收轉發的流數據。
    • SFU服務器
      • 維護流路由表(記錄每個流的發布者與訂閱者列表)。
      • 通過傳輸層協議(如UDP、WebRTC DataChannel)接收和轉發流數據,不涉及媒體層處理。
  • 數據流向

    1. 發布者通過RTMP/WebRTC等協議將流推至SFU。
    2. SFU解析流元數據(如流ID),存儲到路由表。
    3. 訂閱者向SFU請求訂閱某個流ID。
    4. SFU根據路由表,將該流的數據包復制并轉發給所有訂閱者。

2. 與MCU模式的本質區別

維度SFU模式MCU模式(Multipoint Control Unit)
媒體處理不解碼、不混流,僅轉發原始數據包解碼所有流,混合成單一流(如將多路視頻合成畫中畫)
延遲極低(僅網絡傳輸延遲+轉發處理時間)高(需解碼、混流、重新編碼,引入處理延遲)
帶寬消耗發布者推1路流,訂閱者接收N路流(總帶寬≈發布帶寬×N)發布者推N路流,服務器混流后推1路流(總帶寬≈發布帶寬×N + 混流帶寬)
計算資源幾乎無媒體處理消耗,適合高并發需大量CPU/GPU資源,并發量受限
典型場景實時互動直播、多人視頻會議(如Zoom)低并發、需要畫面合成的場景(如傳統視頻會議)

三、SFU模式的技術優勢與適用場景
1. 核心優勢

  • 低延遲特性

    • 無解碼-編碼環節,延遲通常控制在100ms-500ms級別,滿足實時互動需求(如連麥、彈幕互動)。
    • 對比:傳統CDN直播延遲約2-3秒,MCU模式延遲約500ms-1秒。
  • 高擴展性與低資源消耗

    • 服務器僅負責轉發,單臺SFU可支持數萬路流并發轉發(取決于網絡帶寬)。
    • 節省計算資源,適合構建大規模實時通信系統(如在線教育平臺、電商直播)。
  • 靈活性與兼容性

    • 支持多協議接入(WebRTC、RTMP、SRT等),通過轉協議網關實現跨終端互通(如瀏覽器WebRTC流轉發給RTMP推流的手機端)。
    • 支持動態路由:可根據訂閱者網絡質量動態選擇轉發策略(如丟棄高延遲訂閱者的流,或啟用FEC增強可靠性)。

2. 典型應用場景

  • 實時互動直播

    • 場景:主播與觀眾連麥、多人PK直播。
    • 實現:主播推流至SFU,觀眾訂閱主播流;連麥者推流至SFU,SFU將連麥者流轉發給主播和其他觀眾。
    • 案例:Twitch的低延遲直播、B站“直播連麥”功能。
  • 視頻會議系統

    • 場景:百人以上的遠程會議,需支持動態加入/退出。
    • 實現:每個參會者發布自己的流至SFU,根據會議布局(如“發言人模式”),SFU將主講人流轉發給所有參會者。
    • 案例:Zoom的“分組討論”功能基于SFU實現動態流轉發。
  • 物聯網與實時監控

    • 場景:多個攝像頭實時回傳畫面至監控中心,支持多用戶實時查看。
    • 實現:攝像頭通過RTSP推流至SFU,監控客戶端訂閱指定攝像頭流,SFU按需轉發。

2 srs流媒體服務器

2.1 SFU轉發單位

  1. 流接收與注冊
    • 協議適配:支持 WebRTC 協議,接收客戶端(發布者)通過 WebRTC 推來的音視頻流 ,也可處理 RTMP 等其他協議轉 WebRTC 后的流,通過如/rtc/v1/publish/接口邏輯,解析流的元數據(如流 ID、編碼格式、分辨率等) 。
    • 流注冊:將接收的流信息(流 ID、發布者標識等)記錄到內部“流路由表”,建立“流 - 發布者”映射關系,為后續轉發做準備 。
  2. 訂閱與轉發決策
    • 訂閱請求處理:當其他客戶端(訂閱者)通過/rtc/v1/play或 WebRTC 協議發起訂閱請求時,SRS 依據請求中的流 ID,查詢“流路由表”,確定對應的發布者流 。
    • 轉發策略
      • 選擇性轉發:作為 SFU,不解碼、不混流原始媒體流(或僅做輕量級處理,如適配編碼格式),直接復制流數據,根據訂閱關系轉發給訂閱者 。比如多人會議場景,把發言人的單路流,轉發給所有參會訂閱者,實現“一對多”高效分發 。
      • 智能適配:結合客戶端網絡狀況(如帶寬、延遲)、終端能力(支持編碼格式),動態調整轉發的流參數。若訂閱者網絡差,可轉發低分辨率、低碼率流;若終端不支持 VP8 編碼,轉換為 H.264 再轉發 。
  3. 媒體傳輸與優化
    • 傳輸協議:基于 UDP 傳輸媒體數據包(WebRTC 常用方式),利用其低延遲特性;也適配 TCP,應對復雜網絡環境 。
    • 網絡優化
      • NAT 穿透:配合 STUN/TURN 服務器,或通過配置candidate(候選地址),解決客戶端處于 NAT 環境下的互聯互通問題,讓流順利收發 。
      • 擁塞控制:支持 NACK(丟包重傳)、TWCC(傳輸帶寬估計與擁塞控制反饋),檢測到丟包時重傳關鍵數據,根據網絡帶寬動態調整發送碼率,保障流傳輸穩定 。
      • FEC(前向糾錯):添加冗余數據,訂閱者收到數據后,可通過冗余數據恢復丟失的數據包,降低重傳依賴,減少延遲 。
  4. 管理與協同
    • 控制臺管理:提供 srs 1985 控制臺(對應 URL 可查看),可視化展示 SRS 服務狀態、流信息、客戶端連接情況,方便運維人員監控流轉發狀態、排查問題 。
    • 信令協同:與信令服務器(如signal1989 )配合,通過/sig/v1/rtc等接口,處理房間創建、加入、流訂閱/取消等信令邏輯,協同完成“發布 - 訂閱”全流程 。比如信令通知 SRS 有新訂閱者加入,SRS 即刻啟動對應流的轉發 。
  5. 協議轉換與兼容(可選拓展):除純 WebRTC 流轉發,還支持協議轉換。如把 WebRTC 流轉為 RTMP/FLV ,供不支持 WebRTC 的終端(如老舊播放器通過 srs_player.html 播放)使用;也能將 RTMP 流轉為 WebRTC 流輸出,打通不同協議終端的實時通信 。

2.2 信令服務器

信令的本質:
信令服務器核心職責是 處理設備 / 客戶端之間的 “協商邏輯”,比如 WebRTC 里的 SDP 交換(協商編解碼、媒體能力)、房間管理(加入 / 退出、流訂閱關系)、ICE 候選交換(網絡地址協商)等,讓終端知道 “和誰連、怎么連、發什么流” 。
SRS 對信令的支持方式:

  • SRS 可通過 集成簡易信令邏輯 或 對接獨立信令服務器,輔助流媒體業務:
    內置輕量信令功能:
    支持 WHIP(WebRTC HTTP 推流協議 )、WHEP(WebRTC HTTP 拉流協議 )等,可在協議層面處理部分 “推流 - 拉流” 的信令交互(如 SDP 協商、流標識綁定 )。
    例如,客戶端通過 WHIP 協議向 SRS 推流時,SRS 會解析請求里的 SDP 信息,完成媒體能力協商,這一步涉及 “信令式” 的交互,但僅圍繞流媒體傳輸本身,并非完整的 “房間管理、多終端協同” 信令邏輯。
  • 對接獨立信令服務器:
    實際復雜場景(如多人會議)中,SRS 通常搭配 獨立信令服務器(如開源的 Janus 信令模塊、或業務自定義的信令服務 )。
    信令服務器負責處理 “房間創建、用戶加入 / 退出、流訂閱關系同步” 等高層邏輯,再將 “誰需要推流、誰需要拉流” 的指令告知 SRS,由 SRS 執行實際的媒體轉發。

2.3 綜合示例

背景設定

  • 信令服務器:負責房間管理、狀態同步,提供 join/publish/subscribe 等信令接口。
  • SRS(SFU):負責媒體流轉發,提供 publish(推流)和 play(拉流)的媒體接口。
  • 用戶角色
    • CWR:先加入房間的用戶,發布自己的流。
    • CZ:后加入房間的用戶,訂閱 CWR 的流,同時發布自己的流讓 CWR 訂閱。

流程拆解(Step by Step)

1. CWR 加入房間(join 信令)

  • CWR 操作
    調用信令服務器的 join 接口,參數:roomId=1001userId=CWR

    // CWR 發送給信令服務器的 join 請求
    {"action": "join","roomId": "1001","userId": "CWR"
    }
    
  • 信令服務器邏輯

    1. 檢查房間 1001 是否存在,若不存在則創建。
    2. 記錄 CWR 為房間 1001 的參與者,維護“房間 - 參與者列表”:{"1001": ["CWR"]}
    3. 返回房間當前狀態給 CWR:
      // 信令服務器返回給 CWR 的響應
      {"code": 0,"roomId": "1001","participants": ["CWR"], // 目前只有自己"streams": [] // 暫時沒有流發布
      }
      

2. CWR 發布流(publish 信令 + SRS 推流)

  • CWR 操作

    1. 調用信令服務器的 publish 接口,告知“要發布流”:
      {"action": "publish","roomId": "1001","userId": "CWR","streamId": "CWR_stream" // 自定義流標識
      }
      
    2. 通過 WebRTC 協議,將本地攝像頭/麥克風采集的流,推送到 SRS 的 publish 地址(如 webrtc://srs.server/1001/CWR_stream )。
  • 信令服務器邏輯

    1. 記錄“CWR 發布了流 CWR_stream”,更新房間流列表:{"1001": {"streams": ["CWR_stream"]}}
    2. 向房間內所有參與者(目前只有 CWR 自己)推送流發布事件
      {"action": "stream_published","roomId": "1001","userId": "CWR","streamId": "CWR_stream","streamUrl": "webrtc://srs.server/1001/CWR_stream" // SRS 流地址
      }
      
  • SRS(SFU)邏輯

    1. 接收 CWR 推來的 WebRTC 流,解析流元數據(編碼、分辨率等)。
    2. 建立“流標識(CWR_stream)- 發布者(CWR)”的映射,等待訂閱者。

3. CZ 加入房間(join 信令)

  • CZ 操作
    調用信令服務器的 join 接口,參數:roomId=1001userId=CZ

    {"action": "join","roomId": "1001","userId": "CZ"
    }
    
  • 信令服務器邏輯

    1. 檢查房間 1001 已存在,將 CZ 加入參與者列表:{"1001": ["CWR", "CZ"]}
    2. 返回房間當前狀態給 CZ,包含已存在的參與者和流
      {"code": 0,"roomId": "1001","participants": ["CWR", "CZ"],"streams": [{"userId": "CWR","streamId": "CWR_stream","streamUrl": "webrtc://srs.server/1001/CWR_stream"}]
      }
      
    3. 向房間內其他參與者(CWR) 推送新成員加入事件
      {"action": "participant_joined","roomId": "1001","userId": "CZ"
      }
      

4. CZ 訂閱 CWR 的流(subscribe 信令 + SRS 拉流)

  • CZ 操作
    從信令服務器返回的 streams 中,拿到 CWR 的流地址 webrtc://srs.server/1001/CWR_stream,調用信令服務器的 subscribe 接口(或直接通過 WebRTC 發起 play 請求 ):

    {"action": "subscribe","roomId": "1001","userId": "CZ","streamUrl": "webrtc://srs.server/1001/CWR_stream"
    }
    
  • 信令服務器邏輯
    記錄“CZ 訂閱了 CWR 的流”,并通知 SRS 處理轉發。

  • SRS(SFU)邏輯

    1. 收到 CZ 的 play 請求(對應 webrtc://srs.server/1001/CWR_stream )。
    2. 找到 CWR 發布的流,直接轉發給 CZ(不解碼、不混流,僅做網絡優化 )。

5. CZ 發布自己的流(publish 信令 + SRS 推流)

  • CZ 操作

    1. 調用信令服務器的 publish 接口,告知“要發布流”:
      {"action": "publish","roomId": "1001","userId": "CZ","streamId": "CZ_stream"
      }
      
    2. 通過 WebRTC 協議,將本地流推送到 SRS 的 publish 地址(如 webrtc://srs.server/1001/CZ_stream )。
  • 信令服務器邏輯

    1. 記錄“CZ 發布了流 CZ_stream”,更新房間流列表。
    2. 向房間內所有參與者(CWR、CZ) 推送流發布事件
      {"action": "stream_published","roomId": "1001","userId": "CZ","streamId": "CZ_stream","streamUrl": "webrtc://srs.server/1001/CZ_stream"
      }
      
  • SRS(SFU)邏輯
    接收 CZ 推來的流,建立“流標識(CZ_stream)- 發布者(CZ)”的映射,等待訂閱者(如 CWR 會觸發訂閱 )。

6. CWR 訂閱 CZ 的流(自動觸發或信令驅動)

  • CWR 操作
    收到信令服務器推送的“CZ 發布流”事件后,自動調用 subscribe 接口(或直接 play ),訂閱 webrtc://srs.server/1001/CZ_stream

  • SRS(SFU)邏輯
    將 CZ 的流轉發給 CWR,此時 CWR 和 CZ 實現雙向音視頻互通(CWR 看/聽 CZ,CZ 看/聽 CWR )。

關鍵協同總結

角色核心動作數據/信令流向作用
CWR(發布者)joinpublish → 推流到 SRS信令服務器 ←→ CWR;SRS ← CWR(媒體流)初始化房間、發布本地流
CZ(訂閱者)join → 訂閱 CWR 流 → publish → 推流信令服務器 ←→ CZ;SRS ←→ CZ(媒體流)加入房間、訂閱他人流、發布自己流
信令服務器管理房間、同步狀態、轉發事件信令服務器 ←→ CWR/CZ指揮“誰連誰、什么時候連”,不碰媒體數據
SRS(SFU)接收流、轉發流(publish/play 接口)SRS ← 發布者(媒體流);SRS → 訂閱者只負責“搬流媒體數據”,依賴信令調度

3 實戰

3.1 srs 流媒體服務器分析

運行命令:./objs/srs -c ./conf/rtc.conf

# WebRTC streaming config for SRS.
# @see full.conf for detail config.listen              1935;
max_connections     1000;
daemon              off;
srs_log_tank        console;http_server {enabled         on;listen          8080;dir             ./objs/nginx/html;
}http_api {enabled         on;listen          1985;
}
stats {network         0;
}
rtc_server {enabled on;listen 8000; # UDP port# @see https://ossrs.net/lts/zh-cn/docs/v4/doc/webrtc#config-candidatecandidate $CANDIDATE;
}vhost __defaultVhost__ {rtc {enabled     on;# @see https://ossrs.net/lts/zh-cn/docs/v4/doc/webrtc#rtmp-to-rtcrtmp_to_rtc off;# @see https://ossrs.net/lts/zh-cn/docs/v4/doc/webrtc#rtc-to-rtmprtc_to_rtmp off;}http_remux {enabled     on;mount       [vhost]/[app]/[stream].flv;}
}

整體功能概述
該配置文件實現了一個基礎的WebRTC流媒體服務,主要包含以下核心功能:

  • RTMP協議支持(端口1935)
  • HTTP文件服務(端口8080)
  • HTTP API管理接口(端口1985)
  • WebRTC服務(UDP端口8000)
  • HTTP-FLV直播流輸出

核心配置項解析

  1. 基礎服務配置
listen              1935;
max_connections     1000;
daemon              off;
srs_log_tank        console;
  • listen 1935:啟用RTMP協議監聽,用于接收傳統RTMP推流
  • max_connections 1000:限制最大客戶端連接數為1000
  • daemon off:不以守護進程方式運行,便于調試
  • srs_log_tank console:日志輸出到控制臺
  1. HTTP服務配置
http_server {enabled         on;listen          8080;dir             ./objs/nginx/html;
}
  • 啟用HTTP文件服務,端口8080
  • 靜態文件目錄指向./objs/nginx/html,可用于存放播放器頁面等靜態資源
  1. HTTP API配置
http_api {enabled         on;listen          1985;
}
  • 啟用HTTP管理API,端口1985
  • 通過該API可以查詢服務器狀態、流信息等,支持RESTful風格

RESTful 不是 “強制標準”,而是一套讓 API 更簡潔、規范的設計風格,核心通過 “資源 URI + HTTP 方法” 定義接口,讓系統交互清晰、易維護。像你之前提到的 SRS 的 HTTP API,若遵循 RESTful 設計,就能用GET /api/streams查列表、POST /api/streams創建流,比自定義復雜參數的接口好理解得多~

HTTPAPI:
HTTP API 雖然不直接參與媒體流的傳輸(由 SFU 模塊負責),但它為 WebRTC 服務提供了 控制平面 的能力:
動態配置 WebRTC 參數:通過 HTTP API 修改 rtc_server 的配置(如端口、候選地址),無需重啟服務。
監控 WebRTC 連接質量:實時查看 WebRTC 客戶端的連接數、丟包率、帶寬使用情況。
管理 WebRTC 房間 / 會話:結合業務邏輯,通過 HTTP API 創建 / 銷毀 WebRTC 會話(如多人會議房間)

  1. WebRTC核心配置
rtc_server {enabled on;listen 8000; # UDP portcandidate $CANDIDATE;
}
  • enabled on:啟用WebRTC服務
  • listen 8000:使用UDP端口8000進行WebRTC數據傳輸(UDP更適合低延遲實時通信)
  • candidate $CANDIDATE:配置ICE候選地址,$CANDIDATE通常會在啟動時被替換為服務器的公網IP或域名,用于NAT穿透
  1. 虛擬主機配置
vhost __defaultVhost__ {rtc {enabled     on;rtmp_to_rtc off;rtc_to_rtmp off;}http_remux {enabled     on;mount       [vhost]/[app]/[stream].flv;}
}
  • WebRTC相關配置

    • rtc.enabled on:在默認虛擬主機上啟用WebRTC功能
    • rtmp_to_rtc off:關閉RTMP到WebRTC的轉換(不將RTMP流轉換為WebRTC流)
    • rtc_to_rtmp off:關閉WebRTC到RTMP的轉換(不將WebRTC流轉換為RTMP流)
  • HTTP-FLV配置

    • http_remux.enabled on:啟用HTTP-FLV流輸出
    • mount [vhost]/[app]/[stream].flv:定義HTTP-FLV流的訪問路徑格式,例如:http://server:8080/live/stream.flv

3.2 信令服務器分析

SRS 中第三方庫的信令服務器是一個用 Go 語言開發的組件,位于 SRS 的3rdparty/signaling目錄下,默認監聽 1989 端口。它在 SRS 的 WebRTC 功能中扮演著重要角色,主要負責以下任務:

  • 房間管理:處理與房間相關的操作,包括創建房間、加入房間、離開房間等。例如,當用戶想要加入一個特定的視頻通話房間時,信令服務器會對該請求進行處理,確保用戶能夠正確地加入到指定房間。
  • 用戶信息管理:負責管理參與 WebRTC 會話的用戶信息,如用戶的昵稱、狀態等。它可以跟蹤房間內的用戶列表,當有新用戶加入或現有用戶離開時,及時更新相關信息并通知其他用戶。
  • 信令交互:作為客戶端之間信令消息的中轉站,處理 WebRTC 客戶端之間的信令交互,包括協商媒體能力、交換會話描述協議(SDP)信息、處理 ICE(Interactive Connectivity Establishment)候選等。比如,在多人視頻通話中,信令服務器會將一個用戶的媒體流信息轉發給其他用戶,使得各方能夠建立起正確的媒體連接。
cd ~/git/srs/trunk/3rdparty/signaling && make && ./objs/signaling

3.3 http-static

#運行命令
cd ~/git/srs/trunk/3rdparty/httpx-static && make &&
./objs/httpx-static -http 80 -https 443 -ssk server.key -ssc server.crt \-proxy http://127.0.0.1:1989/sig -proxy http://127.0.0.1:1985/rtc \-proxy http://127.0.0.1:8080/

httpx-static 是一個基于 C++ 開發的高性能 HTTP/HTTPS 反向代理服務器,主要用于將客戶端的 HTTP/HTTPS 請求轉發到后端的多個目標服務(如 API 接口、其他服務器等)

在這里插入圖片描述

一、按請求類型拆分:HTTP vs WebSocket
httpx-static 同時支持 HTTP 請求WebSocket 請求 的轉發,對應不同的業務場景:

1. HTTP 請求轉發(常規接口、靜態文件)

  • 請求示例

    • /rtc/v1/publish/ → 轉發到 srs 1985 http api
    • /console/ng_index.html → 轉發到 srs 1985 控制臺
    • /players/srs_player.html → 轉發到 srs 8080 播放器
  • 作用

    • 靜態文件托管:像 srs_player.html 這類播放器頁面,通過 httpx-static 直接代理到 SRS 的靜態文件服務器(8080 端口),客戶端訪問 http://your-domain/players/srs_player.html 就能加載頁面。
    • API 調用/rtc/v1/publish 是 SRS 的 HTTP API(1985 端口),用于觸發流發布邏輯(如推流到 SRS)。
    • 控制臺訪問/console/ng_index.html 是 SRS 的 Web 管理界面,通過代理統一入口,方便運維人員訪問。

2. WebSocket 請求轉發(信令交互)

  • 請求示例

    • /sig/v1/rtc → 轉發到 signal1989 信令服務器(WebSocket 協議)
  • 作用
    WebRTC 信令交互(如房間創建、SDP 交換、ICE 候選協商)依賴 WebSocket 長連接httpx-static 作為代理,將客戶端的 WebSocket 請求(ws://your-domain/sig/v1/rtc)轉發到信令服務器(1989 端口),確保實時信令能穩定傳輸。

二、路由邏輯:“流量分發規則”
httpx-static 通過 路徑匹配 決定請求轉發到哪個后端:

請求路徑協議轉發目標作用
/rtc/v1/publish/HTTPsrs 1985 http api調用 SRS 的流發布 API
/console/ng_index.htmlHTTPsrs 1985 控制臺訪問 SRS 管理界面
/players/srs_player.htmlHTTPsrs 8080 播放器加載 SRS 播放器靜態頁面
/sig/v1/rtcWebSocketsignal1989 信令服務器WebRTC 信令交互(房間、流協商)

三、業務價值:為什么需要這個“中樞”?
1. 統一入口,簡化客戶端配置

  • 客戶端只需記住 httpx-static 的地址(如 http://your-domain),無需關心后端多個服務的具體端口(1985、8080、1989 等)。
  • 示例:
    • 播放器頁面地址統一為 http://your-domain/players/srs_player.html,無需拼接 :8080 端口。
    • 信令連接地址統一為 ws://your-domain/sig/v1/rtc,無需關心信令服務器的 1989 端口。

2. 協議轉換與兼容

  • httpx-static 可以將 外部 HTTPS 請求 轉換為內部 HTTP 請求,反之亦然。
  • 示例:
    • 客戶端用 https://your-domain 訪問(更安全),httpx-static 內部轉發到 SRS 的 HTTP 服務(1985、8080 等),無需后端服務單獨配置 HTTPS。

3. 隱藏后端細節,提升安全性

  • 后端服務(如信令服務器 1989 端口)無需暴露到公網,只需在內部網絡與 httpx-static 通信。
  • 減少公網暴露的端口數量,降低被攻擊的風險(如 1989 端口不直接對外,僅通過 httpx-static 代理)。

4. 支持復雜業務流程

  • 比如 WebRTC 推流流程:
    1. 客戶端通過 HTTP 請求 /rtc/v1/publish 告訴 SRS “我要推流”。
    2. 通過 WebSocket 連接 /sig/v1/rtc 與信令服務器協商推流參數。
    3. 最終音視頻流通過 SRS 的 SFU 模塊傳輸,但所有“控制面”請求都由 httpx-static 統一路由。

四、類比理解:把 httpx-static 當“小區門衛”

  • 客戶端 = 小區居民,想訪問小區內的不同設施(健身房、物業、快遞柜)。
  • httpx-static = 小區門衛,負責登記居民需求,然后幫居民把請求轉發到對應的設施:
    • 居民說“我要去健身房” → 門衛指引到健身房(轉發到 srs 8080 播放器)。
    • 居民說“我要找物業開證明” → 門衛指引到物業辦公室(轉發到 srs 1985 控制臺)。
    • 居民說“我要收發快遞” → 門衛指引到快遞柜(轉發到 signal1989 信令服務器)。

這樣,居民(客戶端)無需記住每個設施的具體位置(端口),只需找門衛(httpx-static)即可~

3.4 交互流程

在這里插入圖片描述
以下結合 httpx-static 代理SRS(SFU)信令服務器 與這張前端交互流程圖,完整拆解 “用戶 → 前端 → 后端服務” 的交互邏輯,理解從“進入網頁”到“音視頻互通”的全流程:

一、核心角色回顧

  1. 前端側

    • one2one.html:前端頁面(用戶入口)。
    • srs.sig.js:信令交互工具庫(處理 WebSocket 連接、收發信令)。
    • srs.sdk.js:WebRTC 工具庫(處理音視頻采集、發布、訂閱)。
  2. 后端側

    • httpx-static:反向代理(統一入口,轉發 HTTP/WebSocket 請求)。
    • SRS(SFU):流媒體服務器(處理音視頻流的發布、訂閱、轉發)。
    • 信令服務器:處理房間管理、SDP 協商、ICE 候選交換等信令邏輯。

二、流程拆解(從“用戶進入網頁”到“音視頻互通”)

1. 初始化階段:前端加載與配置

  • 用戶操作:用戶 1 訪問 one2one.html 頁面(進入網頁)。
  • 前端邏輯
    1. one2one.html 加載后,調用 srs.sig.jsSrsRtcSignalingParse 方法,解析配置:
      • 返回 wsHost(WebSocket 信令地址,如 ws://your-domain/sig/v1/rtc,實際由 httpx-static 代理)。
      • 返回 room(房間 ID,如 1234)、display(用戶標識,如 user1)等參數。

2. 信令連接階段:建立 WebSocket 通道

  • 前端邏輯
    1. 調用 srs.sig.jsSrsRtcSignalingAsync 方法,基于 wsHost 創建 WebSocket 連接:
      • 返回 sig 對象(封裝了 WebSocket 收發信令的能力)。
    2. 通過 sig.connect() 發起 WebSocket 連接,請求到達 httpx-static
  • httpx-static 轉發
    • 識別路徑 /sig/v1/rtc,將 WebSocket 請求轉發到 信令服務器(如 signal1989)。
  • 信令服務器邏輯
    • 接受連接,為用戶 1 分配信令通道,等待后續消息。

3. 加入房間階段:信令交互(join

  • 前端邏輯
    1. 通過 sig.send({ action: 'join', room: '1234', display: 'user1' }) 發送 join 信令。
    2. 信令內容:告知信令服務器“用戶 1 要加入房間 1234”。
  • 信令服務器邏輯
    1. 檢查房間 1234 是否存在,若不存在則創建。
    2. 記錄用戶 1 為房間成員,返回房間信息(如現有成員、流列表)。
    3. 若有其他用戶(如用戶 2)已在房間,信令服務器會向用戶 2 推送“新成員加入”事件。

4. 發布流階段:采集并推送音視頻(publish

  • 前端邏輯
    1. 調用 srs.sdk.jsnew SrsRtcPublisherAsync() 方法,初始化發布器:
      • 請求瀏覽器權限(攝像頭、麥克風),采集音視頻流。
      • 返回 Publisher 對象(封裝了發布流的能力)。
    2. 通過 Publisher.publish() 發起流發布:
      • 生成 WebRTC 的 SDP(媒體能力描述),并通過 sig.send({ action: 'publish', sdp: '...' }) 發送給信令服務器。
  • 信令服務器邏輯
    1. 接收 publish 信令,解析 SDP 內容。
    2. 將 SDP 轉發給 SRS(SFU)(通過 httpx-static 代理的 /rtc/v1/publish 接口)。
  • SRS(SFU)邏輯
    1. 接收 SDP,創建流發布通道,返回 SRS 的 SDP 響應(包含 ICE 候選等網絡信息)。
    2. 信令服務器將 SRS 的響應回傳給前端 Publisher

5. 訂閱流階段:接收對方音視頻(用戶 2 同理)

  • 用戶 2 流程
    用戶 2 重復 步驟 1-4,加入房間 1234 并發布自己的流。
  • 信令服務器通知
    當用戶 2 發布流后,信令服務器向用戶 1 推送“新流發布”事件(包含用戶 2 的流地址,如 webrtc://your-domain/1234/user2)。
  • 前端訂閱邏輯
    1. 用戶 1 的 srs.sdk.js 收到事件后,調用 new SrsRtcSubscriberAsync() 初始化訂閱器。
    2. 通過訂閱器請求 SRS(SFU)拉取用戶 2 的流,建立 WebRTC 連接。

6. 音視頻互通階段:媒體流傳輸

  • SRS(SFU)角色
    • 接收用戶 1 的流(通過 WebRTC 推流),并轉發給用戶 2。
    • 接收用戶 2 的流(通過 WebRTC 推流),并轉發給用戶 1。
  • 前端呈現
    • 用戶 1 和用戶 2 的瀏覽器通過 srs.sdk.js 渲染對方的音視頻流,實現“一對一通話”。

三、關鍵交互鏈路總結

用戶1 one2one.html srs.sig.js srs.sdk.js httpx-static 信令服務器 SRS(SFU) User2 進入網頁 SrsRtcSignalingParse() wsHost/room/display SrsRtcSignalingAsync() sig對象 sig.connect() WebSocket連接 (/sig/v1/rtc) 轉發WebSocket連接 sig.send(join) 發送join信令 返回房間信息 new SrsRtcPublisherAsync() Publisher對象 Publisher.publish() sig.send(publish) 發送publish信令 轉發publish請求 (/rtc/v1/publish) 返回SDP/ICE信息 回傳SDP/ICE 建立WebRTC推流 轉發音視頻流 用戶2執行相同流程后,SRS轉發雙方流,實現互通 用戶1 one2one.html srs.sig.js srs.sdk.js httpx-static 信令服務器 SRS(SFU) User2

四、核心協同點

  1. httpx-static 的“橋梁作用”

    • 統一代理 HTTP(如 /rtc/v1/publish)和 WebSocket(如 /sig/v1/rtc)請求,讓前端只需訪問一個域名,簡化配置。
  2. 信令服務器的“指揮作用”

    • 管理房間、用戶、流的狀態,協調 SRS 轉發媒體流,讓“誰該推流、誰該拉流”邏輯清晰。
  3. SRS(SFU)的“管道作用”

    • 專注媒體流的轉發,不處理業務邏輯,確保音視頻傳輸低延遲、高性能。
  4. 前端 SDK 的“工具作用”

    • srs.sig.js 封裝信令交互,srs.sdk.js 封裝 WebRTC 能力,讓前端開發者無需關注復雜的協議細節。

五、類比理解:把整個流程當“線上電話亭”

  • one2one.html = 電話亭的“操作面板”(用戶輸入要撥打的號碼)。
  • srs.sig.js = 電話亭的“信號線路”(負責傳遞“撥號、接聽”等信令)。
  • srs.sdk.js = 電話亭的“話筒+聽筒”(負責采集、播放聲音/畫面)。
  • httpx-static = 電話局的“總機”(統一轉接所有通話請求)。
  • 信令服務器 = 電話局的“交換機”(決定“誰能接通誰、怎么接通”)。
  • SRS(SFU) = 電話局的“傳輸線路”(負責把聲音/畫面從 A 傳到 B)。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/84860.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/84860.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/84860.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

OpenCV CUDA模塊圖像變形------對圖像進行上采樣操作函數pyrUp()

操作系統:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 編程語言:C11 算法描述 函數用于對圖像進行 上采樣操作(升采樣),是 GPU 加速版本的 高斯金字塔向上采樣(Gaussian Pyrami…

勒貝格測度、勒貝格積分

又要接觸測度論了。隨著隨機規劃的不斷深入,如果涉及到證明部分,測度論的知識幾乎不可或缺。 測度論的相關書籍,基本都非常艱澀難讀,對于非數學專業出身的人入門非常不易。從十幾年前開始,我很難把測度論教材看到超過…

UE5 學習系列(一)創建一個游戲工程

這個系類筆記用來記錄學習 UE 過程中遇到的一些問題與解決方案。整個博客的動機是在使用 AirSim 中遇到了不少性能瓶頸,因此想要系統性地去學一下 UE ,這個系列博客主要是跟著 B 站大佬 歐醬~ 和 GenJi是真想教會你 的系列視頻 《500 分鐘學會…

Nginx 負載均衡、高可用及動靜分離

Nginx 負載均衡、高可用及動靜分離深度實踐與原理剖析 在互聯網應用架構不斷演進的今天,如何高效地處理大量用戶請求、保障服務的穩定性與性能,成為開發者和運維人員面臨的關鍵挑戰。Nginx 作為一款高性能的 Web 服務器和反向代理服務器,憑借…

stm32溫濕度-超聲波-LCD1602結合項目(Proteus仿真程序)

資料下載地址:stm32溫濕度-超聲波-LCD1602結合項目(Proteus仿真程序) 程序實現功能: 程序基于stm32芯片實現了控制LED燈亮滅、按鍵控制、串口通信、電機控制、溫濕度數據采集、超聲波測距、LCD顯示屏顯示內容這幾個功能,并用proteus8進行仿…

新一代python管理工具--uv

uv 工具全方位介紹 起源與背景 uv 是由 Astral(pipx 作者)團隊用 Rust 語言開發的新一代 Python 包和環境管理工具。其目標是解決傳統 pip/venv/conda 在依賴解析慢、環境隔離繁瑣、命令復雜等方面的痛點,為現代 Python 項目提供極速、自動…

路由交換技術-思科拓撲搭建

配置流程 1.搭建網絡拓撲圖。 2.規劃配置IP地址,內網配置為192.168.1.0和192.168.2.0網段。 3.劃分vlan10,vlan20,vlan30。 4.配置靜態、動態路由。配置路由器Router7,使內外網互通。 5.配置鏈路聚合。通過鏈路聚合技術&#xff…

清華大學視覺空間智能新突破!Spatial-MLLM:提升多模態大語言模型的視覺空間智能能力

作者:Diankun Wu, Fangfu Liu, Yi?Hsin Hung, Yueqi Duan 單位:清華大學 論文標題:Spatial-MLLM: Boosting MLLM Capabilities in Visual-based Spatial Intelligence 論文鏈接:https://arxiv.org/pdf/2505.23747 項目主頁&a…

AI與機器學習ML:利用Python 從零實現神經網絡

自線性回歸以來,我們已經涵蓋了很多領域。在本期中,我們將開始了解神經網絡內部工作原理的旅程*。* 如果一個人試圖了解任何使用生成式 AI 的工具、應用程序、網站或其他系統的內部工作原理,那么掌握神經網絡的架構至關重要。在這個故事中&a…

Vim 匹配跳轉與搜索命令完整學習筆記

Vim 匹配跳轉與搜索命令完整學習筆記 文章目錄 Vim 匹配跳轉與搜索命令完整學習筆記1. 括號/結構匹配% - 括號匹配跳轉[[ / ]] - 函數定義跳轉[{ / ]} - 代碼塊邊界跳轉 2. 精確單詞搜索* - 向下精確搜索# - 向上精確搜索 3. 模糊單詞搜索g* - 向下模糊搜索g# - 向上模糊搜索 4…

安卓9.0系統修改定制化____系列 ROM解打包 修改 講解 導讀篇

專欄系列前言: 💝💝💝本專欄作者從事rom系統修改以及手機維修 刷機多年。從當年山寨機開始。歷經安卓4.--至目前的安卓15.合作伙伴遍及各類工作室以及PDA商家 私人玩友等。在廣告機 平板 pda設備 會議機 車機的rom修改中略有經…

Vue3本地存儲實現方案

在 Vue 3 中實現本地存儲(如用戶配置數據),主要通過瀏覽器提供的 localStorage 或 sessionStorage API。以下是詳細實現方案: 基礎實現(原生 API) javascript 復制 下載 // 存儲數據 localStorage.set…

計算機視覺與深度學習 | 2024年至2025年圖像匹配算法總結(原理,公式,代碼,開源鏈接)

圖像匹配算法 一、核心算法分類與技術路線1. **傳統局部特征 + 匹配優化**(魯棒性強,適合資源受限場景)2. **端到端密集匹配網絡**(高精度,適合復雜形變/弱紋理)3. **基于光流思想的匹配網絡**4. **2024-2025年新趨勢**二、核心開源工具庫匯總三、典型代碼流程(以LoFTR為…

瑞芯微 MIPI D-PHY 接收器(RX)驅動學習筆記

驅動文件位置 driver/phy/rockchip/phy-rockchip-mipi-rx.c 1 重要結構體 struct mipidphy_priv {struct device *dev;//表示與驅動程序關聯的設備。它用于設備管理,如設備注冊、注銷等。struct regmap *regmap_grf;//用于映射和訪問通用寄存器文件(Gen…

MySQL從入門到DBA深度學習指南

目錄 引言 MySQL基礎入門 數據庫基礎概念 MySQL安裝與配置 SQL語言進階 數據庫設計與規范化 數據庫設計原則 表結構設計 MySQL核心管理 用戶權限管理 備份與恢復 性能優化基礎 高級管理與高可用 高可用與集群 故障診斷與監控 安全與審計 DBA實戰與運維 性能調…

多個機器人同時加載在rviz及gazebo同一個場景中

1. 配置launch文件 gazebo的加載相對容易,但rviz中加載,需要構建完整的tf樹(world → map(或map_merged)→ odom → base_footprint → base_link → base_scan)才能正常顯示,launch文件主要是…

Text2SQL、Text2API基礎

你有一個能力超強但“不太懂行”的助手(大語言模型LLM)。它能說會道,知識淵博,但它: 不懂你的數據庫: 不知道你的數據庫里有哪些表,表里有哪些字段,這些字段代表什么意思。不懂你的…

JDK 8u231安裝教程 - Windows 64位下載安裝及環境變量配置指南

下載安裝包 把jdk-8u231-windows-x64.exe這個文件下載下來,下載鏈接:https://pan.quark.cn/s/a610ca7e5e9d,隨便放哪兒,比如桌面或者下載文件夾。 雙擊運行安裝 找到下載好的那個exe文件,直接雙擊打開。可能會彈個窗口…

LatentSync V8版 - 音頻驅動視頻生成數字人說話視頻 更新V1.6版模型 支持50系顯卡 支持批量 一鍵整合包下載

LatentSync 是字節跳動開源的一款"AI口型同步神器",簡單來說就是能讓視頻里的人物嘴巴動得和聲音完美匹配的工具。比如你給一段配音,它能自動調整視頻人物的嘴型,按照配音里的聲音說出來,就像真人說話一樣自然。簡單說就…

從一組線段中得出四邊形的算法

原始的需求是使用OpenCV的直線檢測算法(例如LSD)之后,得到一組線段。然后需要從這些線段得到類似矩形的四邊形,用于檢測經過透視變換的矩形物體。這些線段不一定首尾相接,彼此之間可能相交或有一定距離。 以下是需求圖…