Yin的笔记本

vuePress-theme-reco Howard Yin    2021 - 2025
Yin的笔记本 Yin的笔记本

Choose mode

  • dark
  • auto
  • light
Home
Category
  • CNCF
  • Docker
  • namespaces
  • Kubernetes
  • Kubernetes对象
  • Linux
  • MyIdeas
  • Revolution
  • WebRTC
  • 云计算
  • 人工智能
  • 分布式
  • 图像处理
  • 图形学
  • 微服务
  • 数学
  • OJ笔记
  • 博弈论
  • 形式语言与自动机
  • 数据库
  • 服务器运维
  • 编程语言
  • C
  • Git
  • Go
  • Java
  • JavaScript
  • Python
  • Nvidia
  • Rust
  • Tex
  • Shell
  • Vue
  • 视频编解码
  • 计算机网络
  • SDN
  • 论文笔记
  • 讨论
  • 边缘计算
  • 量子信息技术
Tag
TimeLine
About
查看源码
author-avatar

Howard Yin

303

Article

153

Tag

Home
Category
  • CNCF
  • Docker
  • namespaces
  • Kubernetes
  • Kubernetes对象
  • Linux
  • MyIdeas
  • Revolution
  • WebRTC
  • 云计算
  • 人工智能
  • 分布式
  • 图像处理
  • 图形学
  • 微服务
  • 数学
  • OJ笔记
  • 博弈论
  • 形式语言与自动机
  • 数据库
  • 服务器运维
  • 编程语言
  • C
  • Git
  • Go
  • Java
  • JavaScript
  • Python
  • Nvidia
  • Rust
  • Tex
  • Shell
  • Vue
  • 视频编解码
  • 计算机网络
  • SDN
  • 论文笔记
  • 讨论
  • 边缘计算
  • 量子信息技术
Tag
TimeLine
About
查看源码
  • ION的基本架构

    • 启动
      • SFU
      • islb
      • Signal

ION的基本架构

vuePress-theme-reco Howard Yin    2021 - 2025

ION的基本架构


Howard Yin 2022-04-15 10:57:03 WebRTC编程框架pion概念
服务名称 功能
ISLB 节点发现与负载均衡
Signal 传递信令
Room 主要业务逻辑,包括聊天室、用户验证等
SFU WebRTC SFU,用于视频流的转发
用到的独立软件 功能
Redis 缓存数据库。给ISLB存储节点列表等数据;给Room存储业务逻辑数据
nats 分布式消息队列。用于各服务间的消息传递

Software applications and services need to exchange data. NATS is an infrastructure that allows such data exchange, segmented in the form of messages. We call this a "message oriented middleware".

在连接建立过程中,各组件之间的关系如下:

SDK<---grpc--->signal<---nats--->Room/ISLB<---nats--->signal<---grpc--->SDK
                                    ||
                                  [Redis]
1
2
3

在视频流传输中,各组件之间的关系如下:

SDK<----webrtc---->SFU<----webrtc---->SDK
1

# 启动

# SFU

在官网教程中,单独启动SFU的指令如下:

docker pull nats
docker run -p 4222:4222 -p 6222:6222 -p 8222:8222 nats
docker run -p 5000:5000/udp --network host -v $PWD/configs/sfu.toml:/configs/sfu.toml pionwebrtc/ion:latest-sfu
1
2
3

可以看出,SFU需要有nats的存在才可运行。

$PWD/configs/sfu.toml似乎是配置文件。找到pion/ion-sfu中配置文件的位置 ,可以看到这文件长这样:

[sfu]
# Ballast size in MiB, will allocate memory to reduce the GC trigger upto 2x the
# size of ballast. Be aware that the ballast should be less than the half of memory
# available.
ballast = 0
# enable prometheus sfu statistics
withstats = false

[router]
# Limit the remb bandwidth in kbps
# zero means no limits
maxbandwidth = 1500
# max number of video tracks packets the SFU will keep track
maxpackettrack = 500
# Sets the audio level volume threshold.
# Values from [0-127] where 0 is the loudest.
# Audio levels are read from rtp extension header according to:
# https://tools.ietf.org/html/rfc6464
audiolevelthreshold = 40
# Sets the interval in which the SFU will check the audio level
# in [ms]. If the active speaker has changed, the sfu will
# emit an event to clients.
audiolevelinterval=1000
# Sets minimum percentage of events required to fire an audio level
# according to the expected events from the audiolevelinterval,
# calculated as audiolevelinterval/packetization time (20ms for 8kHz)
# Values from [0-100]
audiolevelfilter = 20

[router.simulcast]
# Prefer best quality initially
bestqualityfirst = true
# EXPERIMENTAL enable temporal layer change is currently an experimental feature,
# enable only for testing.
enabletemporallayer = false

[webrtc]
# Single port, portrange will not work if you enable this
# singleport = 5000

# Range of ports that ion accepts WebRTC traffic on
# Format: [min, max]   and max - min >= 100
portrange = [5000, 5200]
# if sfu behind nat, set iceserver
# [[webrtc.iceserver]]
# urls = ["stun:stun.stunprotocol.org:3478"]
# [[webrtc.iceserver]]
# urls = ["turn:turn.awsome.org:3478"]
# username = "awsome"
# credential = "awsome"

# sdp semantics:
# "unified-plan"
# "plan-b"
# "unified-plan-with-fallback"
sdpsemantics = "unified-plan"
# toggle multicast dns support: https://tools.ietf.org/html/draft-mdns-ice-candidates-00
mdns = true

[webrtc.candidates]
# In case you're deploying ion-sfu on a server which is configured with
# a 1:1 NAT (e.g., Amazon EC2), you might want to also specify the public
# address of the machine using the setting below. This will result in
# all host candidates (which normally have a private IP address) to
# be rewritten with the public address provided in the settings. As
# such, use the option with caution and only if you know what you're doing.
# Multiple public IP addresses can be specified as a comma separated list
# if the sfu is deployed in a DMZ between two 1-1 NAT for internal and
# external users.
# nat1to1 = ["1.2.3.4"]
# icelite = true

[webrtc.timeouts]
# The duration in [sec] without network activity before a ICE Agent is considered disconnected
disconnected = 5
# The duration in [sec] without network activity before a ICE Agent is considered failed after disconnected
failed = 25
# How often in [sec] the ICE Agent sends extra traffic if there is no activity, if media is flowing no traffic will be sent
keepalive = 2

[turn]
# Enables embeded turn server
enabled = false
# Sets the realm for turn server
realm = "ion"
# The address the TURN server will listen on.
address = "0.0.0.0:3478"
# Certs path to config tls/dtls
# cert="path/to/cert.pem"
# key="path/to/key.pem"
# Port range that turn relays to SFU
# WARNING: It shouldn't overlap webrtc.portrange
# Format: [min, max]
# portrange = [5201, 5400]
[turn.auth]
# Use an auth secret to generate long-term credentials defined in RFC5389-10.2
# NOTE: This takes precedence over `credentials` if defined.
# secret = "secret"
# Sets the credentials pairs
credentials = "pion=ion,pion2=ion2"

[log]
# 0 - INFO 1 - DEBUG 2 - TRACE
v = 1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104

可以看到设置还是比较丰富的,比如有maxbandwidth这种带宽设置、WebRTC监听端口范围设置portrange、给内网端口映射环境部署时用的nat1to1、内置turn服务器设置[turn]等。

但是并没看到有nats相关的配置?这个SFU是怎么知道如何连接nats的?在仔细找找,发现这个pion/ion-sfu并不是直接放进容器里,而是在github.com/pion/ion/pkg/node/sfu 里面做了一层封装,然后在cmd/sfu/main.go 里面调用成为一个可执行文件的。

进一步,进到pkg/node/sfu/sfu.go 中,找到最主要的配置项:

// Config for sfu node
type Config struct {
	Global global   `mapstructure:"global"`
	Log    logConf  `mapstructure:"log"`
	Nats   natsConf `mapstructure:"nats"`
	isfu.Config
}
1
2
3
4
5
6
7

可以看到,SFU中的配置项实际上是几个配置项拼起来的,其中就包含pion/ion-sfu中配置项isfu.Config。

再找到从这个配置项生成的pion/ion中关于SFU的配置文件 :

[global]
# data center id
dc = "dc1"

[nats]
url = "nats://127.0.0.1:4222"


[sfu]
# ......以下配置和上面那个配置文件差不多,省略
1
2
3
4
5
6
7
8
9
10

可以看到这就是pion/ion-sfu中配置文件 加了几个配置项而已。其中就有nats的配置项,比如地址和数据库名称啥的。

具体原理的解析,且看《ION中的SFU服务》。

# islb

在官网教程中,单独启动islb的指令如下:

docker pull nats
docker run -p 4222:4222 -p 6222:6222 -p 8222:8222 nats
docker pull redis
docker run -p 6379:6379 redis
docker run --network host -v $PWD/configs/islb.toml:/configs/islb.toml pionwebrtc/ion:latest-islb
1
2
3
4
5

可以看出,islb不仅需要有nats,还需要有Redis的存在才可运行。毕竟是负载均衡,肯定要存一下有哪些个节点可供负载均衡。

$PWD/configs/islb.toml应该就是配置文件。和上面一样,直接找到对应的配置文件 :

[global]
# data center id
dc = "dc1"

[log]
level = "info"

[nats]
url = "nats://127.0.0.1:4222"


[redis]
addrs = [":6379"]
password = ""
db = 0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

未免也过于简单了,完全就只有连数据库的配置,没有一点自己的运行逻辑方面配置?

从代码结构上看,在pion项目中,这个islb没有单独的包,主要的逻辑都在github.com/pion/ion/pkg/node/islb 这个包里面,然后在cmd/islb/main.go 里面做成可执行文件。找代码里的配置项也很好找得到:

// Config for islb node
type Config struct {
	Global  global    `mapstructure:"global"`
	Log     logConf   `mapstructure:"log"`
	Nats    natsConf  `mapstructure:"nats"`
	Redis   db.Config `mapstructure:"redis"`
	CfgFile string
}
1
2
3
4
5
6
7
8

这里面确实没有islb相关的配置项。这就怪了,这islb是什么运行逻辑,怎么都没配置的?好歹还是个“负载均衡”来着。

这个问题比较复杂,详见《ION中的islb服务》。总的来说,islb实际上就是一个服务注册中心,并没有所谓的负载均衡功能,存储和查询流信息的功能不知道被移到哪去了。推测这个模块后面应该会改个名字,比如改成“Registry”啥的,更符合它现在的功能。

# Signal

从《ION中的SFU服务》中我们可以看出,信令服务都在SFU里面写好了,那这个Signal是干嘛用的?

先看启动过程。在官网教程中,单独启动Signal的指令如下:

docker pull nats
docker run -p 4222:4222 -p 6222:6222 -p 8222:8222 nats
docker run -p 5551:5551/tcp --network host -v $PWD/configs/signal.toml:/configs/signal.toml pionwebrtc/ion:latest-signal
1
2
3

可以看出,Signal的启动只需要有nats就行了

这个配置文件是这样:

[global]
# data center id
dc = "dc1"

[log]
level = "info"
# level = "debug"

[nats]
url = "nats://127.0.0.1:4222"


[signal.grpc]
#listen ip port
host = "0.0.0.0"
port = "5551"
allow_all_origins = true
# cert= "configs/certs/cert.pem"
# key= "configs/certs/key.pem"

[signal.jwt]
enabled = false 
key_type = "HMAC"
key = "1q2dGu5pzikcrECJgW3ADfXX3EsmoD99SYvSVCpDsJrAqxou5tUNbHPvkEFI4bTS"

[signal.svc]
services = ["rtc", "room"]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27

前面都没啥特殊的。

这个signal.grpc应该是指明Signal服务的对外接口;signal.jwt应该是验证功能;signal.svc这是什么,看着像是什么服务名,不知道有什么用?

打开Signal的主函数 看一眼,服务注册之类的代码都和前面介绍的一样,最重要的代码应该就是这段:

	srv := grpc.NewServer(
		grpc.CustomCodec(nrpc.Codec()), // nolint:staticcheck
		grpc.UnknownServiceHandler(nproxy.TransparentLongConnectionHandler(sig.Director)))

	s := util.NewWrapperedGRPCWebServer(util.NewWrapperedServerOptions(
		addr, conf.Signal.GRPC.Cert, conf.Signal.GRPC.Key, true), srv)

	if err := s.Serve(); err != nil {
		log.Panicf("failed to serve: %v", err)
	}
	select {}
1
2
3
4
5
6
7
8
9
10
11

滴滴🤯!!捕捉到关键词proxy!看这样子Signal应该是个GRPC代理,把外面来的标准GRPC请求转换为nats-grpc的请求。

进一步解析详见《ION中的Signal服务》。

帮助我们改善此页面!
创建于: 2022-04-09 12:33:17

更新于: 2022-04-15 10:57:33