什么是单端口
为什么使用单端口:
如何实现单端口:
介绍单端口改造的来历:https://blog.csdn.net/elesos/article/details/82427414
单端口两个方案:
基本的肯定是交换sdp的时候,把ice-ufrage 换成roomid。roomid和client ip,port绑定,区分不同流.
方案1 在janus 加一个proxy.
结构:client --proxy---libnice
所有client都发送到,同一个proxy ip,port(单端口)
1.1 client 发送stun request 到proxy
1.2 proxy 发送stun request 给libnice.(这里需要janus proxy实现stun request协议)
1.3 libnice respond(此处libnice会新创建port )给proxy, proxy转发给client,同时proxy 记录client和libnice 对应的prot
1.4 client rtp 流到proxy,proxy转发给libnice port
等于client到proxy一个udp socket, proxy和libnice 一个udp socket。
方案2: 绕开libnice
也是加一个proxy,但是不发给libnice.因为已经知道了,roomid和client ip,port绑定关系,能够区分出来不同流,不需要再走libnice.
直接proxy到janus.c 。
但是libnice和janus结合比较深,觉得绕过去,应该挺麻烦
单端口结构:
Janus使用了Libnice库作为底层网络传输库,该库本身是多端口的实现,因此要在Janus基础上实现单端口存在两种方案:
1) 直接替换掉Libnice库,重新构建底层,改为单端口的传输方式。但是由于Janus和Libnice库的耦合非常紧密,若要使用重新构建底层的方式,实现较为复杂的,难度很大;
2) 保留Libnice多端口的实现,在Janus上增加单端口代理的功能。
代理的功能是指将单一的对外端口传输的客户端的数据,在接收到数据之后,同时将相应的数据转发到Libnice内部分配的不同服务端的内部端口中。这种方式修改起来会更简单一些。
若选择使用代理方式,实现难点在于来自不同客户端的数据都是通过同一个服务端端口进行传输,服务端该如何判断传输的数据与用户的对应关系。
对此,我们可以通过SDP协商里面的ICE-Ufrag字段进行解决,当服务端接收到客户端的SDP后,1) 按照之前的流程,会创建本地服务的端口,并且将相应的ICE-Ufrag与该端口映射起来。
2) 服务端会将对外的IP端口写入SDP传给客户端,然后一直监听对外端口。
3) 客户端建联时会发送Stun包, Stun包中会带有ICE-Ufrag,服务端接收并解析出ICE-Ufrag,再根据之前的映射关系,从IP-MAPS中找到对应的服务端端口。同时服务端还会记录Stun包的来源客户端IP和端口,服务端就会将用户侧的IP和端口与服务端的IP和端口映射起来。
4) 每次收到客户端的数据之后,就可以查看数据源的IP和端口,通过MAP的映射关系查到对应的服务端的端口,将数据转发到相应的服务端端口中。
同理,服务端发出的数据也会从映射关系中找到对应客户端的IP和端口,通过单个端口发出。
1)在服务器给Web端的SDP Answer中设置 ice-ufrag为roomid/userid,其中RoomID和UserID是通话业务层分配的内容,用于区分每对通话以及参与者。
2) 接着做Ice candidate协商
(1)Web客户端开始做连通性检测,也就是stun binding request里的USERNAME为SDP local和remote的ice-ufrag指定内容.(username is roomid,绑定了peer ip+port)
(2)服务器收到stun binding request的客户端ip和端口,并正常回stun binding response。
(notes: 理解为这个respond给每个client都是相同的ip+port. 原来的ice是如何做的呢?janus ice给每个client的port是不同的吗?每个stun和rtp是使用相同的port吗?)
(3)记录客户端地址与用户的信息的映射关系
3)服务器收到一个rtp/rtcp媒体数据包,通过包的源ip和端口,查询映射表就可以识别这个包属于哪个用户。
notes: proxy 统一端口,不需要给libnice的内部多端口转发吗?
实际的交互过程会比这个更复杂一些, 有时候offer中可能并不包含candate, 可以根据stun binding request 拿到相应的ufrag和远端的ip和地址.
需要注意的是, 这样的模型对于client -> server直接交互的状态下没有什么问题, 但对于多个WebRTC mediaserver 级联的时候会有一些问题, 因为多个流通过在媒体服务器级联的时候会有相同的ip, 这种情况下只能通过ssrc来区分不同的音视频流, 这种情况下个需要保证ssrc不能冲突.
notes:级联是多个流有相同的ip了,不是不同ip了
上面的意思是级联也是单端口了?每个socekt数据都有ssrc吗?



