在初次使用freeswitch的过程中,经常会碰到听不见对方声音的问题。产生这种问题的根本原因还是因为NAT穿越的问题。如果freeswitch和客户端在一个网络上是不会出现这个问题的,主要还是因为freeswitch和客户端一个在内网中,一个在公网中。客户端和freeswitch通信是通过路由器的NAT穿越完成。比如说freeswitch是部署在公网的一台服务器上,而客户端是安装在用户的内网的一台电脑上,这台电脑通过路由器访问互联网。所以这里就存在路由器把内网客户端的地址转换为公网地址的一个过程。
1、客户端和freeswitch之间通信的方式
在说明这个问题之前我还是先来看看客户端和freeswitch是怎么通信的。
这里的客户端指的是可以进行语音或者视频的客户端,它和freeswitch是通过SIP协议通信的,但是中间的语音流或者视频流又是通过SDP协议传输双方地址和编码格式等其他进行媒体协商的必要信息的,真正的语音流或者视频流是通过RTP传输的。那么听不到声音的问题应该是和SDP协议有关,所以我们来详细看一下SDP协议是什么:
SDP协议简介
v=0
o=FreeSWITCH 1598186068 1598186069 IN IP4 39.99.55.147
s=FreeSWITCH
c=IN IP4 39.99.55.147
t=0 0
m=audio 4964 RTP/SAVPF 102 9 0 8 103 101
a=rtpmap:102 opus/48000/2
a=rtpmap:9 G722/8000
a=rtpmap:0 PCMU/8000
a=rtpmap:8 PCMA/8000
a=rtpmap:103 telephone-event/48000
a=rtpmap:101 telephone-event/8000
SDP协议就类似以上这种键值对的形式,它通常不是单独出现的,而是作为SIP协议的报文进行传输。
v=:Version,表示协议的版本号。
o=:Origin,表示源。
s=:Session Name,表示本SDP所描述的Session的名称。
c=:Connection Data,连接数据。其中值域中已空格分配的两个字段分别是网络类型和网络地址,以后的RTP流就会发到该地址上。
t=:Timing,起止时间。0表示无限。
m=:Media Type,媒体类型。audio表示音频。空格后面的数字表示端口号。RTP/SAVPF是传输协议;后面是支持的编码类型。
a=:Attribute,属性。它用于描述上面音频的属性,如本例中的9代表G722编码,0代表PCMU编码。
由于freeswitch有自动NAT转换的功能,所以如果客户端发过来的SDP信息中c中的地址是内网地址,freeswitch也会自动转换成路由器发过来的实际地址。但是客户端就没有这么聪明了,如果客户端解析来自freeswitch的SDP消息中c的内容不是freeswitch的公网地址,那么客户端就不能把语音流发送到正确的地址了。
由于freeswitch的默认配置里面没有把这个c的地址配置中外网地址,所以就会导致我们刚安装完freeswitch听不到客户端声音的情况。由于客户端注册在internal的profile中,所以我们需要在internal.xml中配置以下两个配置项:
<param name="ext-rtp-ip" value="39.99.55.147"/>
<param name="ext-sip-ip" value="39.99.55.147"/>
把这个配置保存后,需要重启freeswitch才能生效。
2、收不到外部网关语音流的解决方法
有时候外部网关也不能自动转换NAT地址,导致不能发送语音流到正确的地址上。和上面一样,网关是注册在external.xml上的,当然要更改external.xml咯,把上面两个配置项写到external.xml中,就可以收到语音流了。
本博客所有文章除特别声明外,均采用 CC BY-SA 3.0协议 。转载请注明出处!