一. 场景
公网部署一台FS SIP服务器,web端通过sipjs连接FS服务器(ws/wss连接)
二. ICE连通性检查:
fs和web客户端的ICE地址进行轮询检查连通性;
由于该场景中web处在内网中,所以连通性检查一个也过不了,反而有明显的耗时。
三. 解决方案:
由于FS处在公网中,FS的 rtp端口是能正常访问,FS能收到web端的stun消息,而这个stun消息就是由web端的RTP端口发出来的,所以FS端可以直接将web端的stun消息的公网地址设置为RTP的公网地址。使用这个地址进行RTP通信。
修改FS代码源码,增加一个ICE联通检查通道变量,ice_immediately。设置该通道变量,这不进行ICE的联通检查
freeswitch 1.10.1 版本,其他版本对照更改
1. src/include/switch_types.h
typedef enum {
ICE_GOOGLE_JINGLE = (1 << 0),
ICE_VANILLA = (1 << 1),
ICE_CONTROLLED = (1 << 2),
ICE_LITE = (1 << 3),
+ ICE_IMMEDIATELY = (1 <<4) //[20200609] by aominle
} switch_core_media_ice_type_t;
static switch_core_media_ice_type_t switch_determine_ice_type(switch_rtp_engine_t *engine, switch_core_session_t *session) {
switch_core_media_ice_type_t ice_type = ICE_VANILLA;
+ //[20200609] by aominle
+ if (switch_channel_var_true(session->channel, "ice_immediately")){
+ ice_type |= ICE_IMMEDIATELY;
+ }
if (switch_channel_var_true(session->channel, "ice_lite")) {
ice_type |= ICE_CONTROLLED;
ice_type |= ICE_LITE;
} else {
switch_call_direction_t direction = switch_ice_direction(engine, session);
if (direction == SWITCH_CALL_DIRECTION_INBOUND) {
ice_type |= ICE_CONTROLLED;
}
}
return ice_type;
}
handle_ice函数
1260行左右
if (cmp) {
ice->last_ok = now;
rtp_session->wrong_addrs = 0;
} else {
if (((rtp_session->dtls && rtp_session->dtls->state != DS_READY) || !ice->ready || !ice->rready) &&
rtp_session->wrong_addrs > 2 && rtp_session->ice_adj == 0) {
do_adj++;
rtp_session->ice_adj = 1;
rtp_session->wrong_addrs = 0;
//- } else if (rtp_session->wrong_addrs > 10 || elapsed >= 10000) {
+ } else if ((ice->type & ICE_IMMEDIATELY) || rtp_session->wrong_addrs > 10 || elapsed >= 10000) { // [ add ICE_IMMEDIATELY, when wrong address , Auto change the from adderss 20200609] by aominle
do_adj++;
}
四。用法
在发起呼叫时增加通道变量 {ice_immediately=true}