初级会员
  • 第 12 位会员
  • janu
  • It_way@163.com
  • 2016-11-04 09:53:57

最近发布的主题

    暂无

最近分享的资源

    暂无

最近发布的项目

    暂无

最近的评论

  • chrome 支持性还好, firefox 支持有 bug
  • 启动 rtpproxy 的时候,有两个可选参数来指定分配 UDP 端口范围 `-m min_port` Set lower limit on UDP ports range that the RTPproxy uses for RTP/RTCP sessions to min_port. Default is 35000. `-M max_port` Set upper limit on UDP ports range that the RTPproxy uses for RTP/RTCP sessions to max_port. Default is 65000.
  • 从你的日志 跟 INVITE -> BYE 小时的间隔时间来看,应该属于 ACK 消息丢失的问题。
  • 401 就是说 要让你带认证信息!
  • 首先,感谢 老李 的帮助 现在来结贴。 上面的问题其实是一个乌龙。 附上 dispatcher 选择 目标节点的 代码: ``` hash = 0; switch(alg) { case 0: /* hash call-id */ if(ds_hash_callid(msg, &hash)!=0) { LM_ERR("can't get callid hash\n"); return -1; } break; case 1: /* hash from-uri */ if(ds_hash_fromuri(msg, &hash)!=0) { LM_ERR("can't get From uri hash\n"); return -1; } break; case 2: /* hash to-uri */ if(ds_hash_touri(msg, &hash)!=0) { LM_ERR("can't get To uri hash\n"); return -1; } break; case 3: /* hash r-uri */ if (ds_hash_ruri(msg, &hash)!=0) { LM_ERR("can't get ruri hash\n"); return -1; } break; case DS_ALG_RROBIN: /* round robin */ hash = idx->last; idx->last = (idx->last+1) % idx->nr; break; case 5: /* hash auth username */ i = ds_hash_authusername(msg, &hash); switch (i) { case 0: /* Authorization-Header found: Nothing to be done here */ break; case 1: /* No Authorization found: Use round robin */ hash = idx->last; idx->last = (idx->last+1) % idx->nr; break; default: LM_ERR("can't get authorization hash\n"); return -1; } break; case 6: /* random selection */ hash = rand() % idx->nr; break; case 7: /* hash on PV value */ if (ds_hash_pvar(msg, &hash)!=0) { LM_ERR("can't get PV hash\n"); return -1; } break; case 8: /* use always first entry */ hash = 0; break; case 9: /* weight based distribution */ hash = idx->wlist[idx->wlast]; idx->wlast = (idx->wlast+1) % 100; break; case DS_ALG_LOAD: /* call load based distribution */ /* only INVITE can start a call */ if(msg->first_line.u.request.method_value!=METHOD_INVITE) { /* use first entry */ hash = 0; alg = 0; break; } if(dstid_avp_name.n==0) { LM_ERR("no dst ID avp for load distribution" " - using first entry...\n"); hash = 0; alg = 0; } else { i = ds_get_leastloaded(idx); if(i<0) { /* no address selected */ return -1; } hash = i; if(ds_load_add(msg, idx, set, hash)<0) { LM_ERR("unable to update destination load" " - classic dispatching\n"); alg = 0; } } break; case 11: /* relative weight based distribution */ hash = idx->rwlist[idx->rwlast]; idx->rwlast = (idx->rwlast+1) % 100; break; default: LM_WARN("algo %d not implemented - using first entry...\n", alg); hash = 0; } ``` 这这里我使用了 根据 CALLID 来求 hash 的算法。在日志中会有如下打印: >Nov 3 18:08:58 localhost ./sbin/kamailio[11536]: DEBUG: dispatcher [dispatch.c:1947]: ds_select_dst_limit(): alg hash [3289283721] 接下来 ``` if(ds_use_default!=0 && idx->nr!=1) hash = hash%(idx->nr-1); else hash = hash%idx->nr; i=hash; /* if selected address is inactive, find next active */ while (ds_skip_dst(idx->dlist[i].flags)) { if(ds_use_default!=0 && idx->nr!=1) i = (i+1)%(idx->nr-1); else i = (i+1)%idx->nr; if(i==hash) { /* back to start -- looks like no active dst */ if(ds_use_default!=0) { i = idx->nr-1; if(ds_skip_dst(idx->dlist[i].flags)) return -1; break; } else { return -1; } } } hash = i; ``` 在这里会把第一次获取到的那个 hash 转成 dispatcher.list 文件中定义的那个 id 序号。while 循环就是从节点列表中找出满足条件的 ACTIVE 状态的一个节点。这个节点就是最终选择的目标地址。 至于在问题中所描述的问题就顺利成章的可以理解了: 关闭 B1, client 想 A 发起注册, A 第一次 ds_select_dst 失败后,调用 ds_mark_dst 把 B1 标记为 INACTIVE, 然后调用 ds_next_select 选择到了 B2, client 成功注册到了 B2 上面; client 发送第二次注册消息上来的,A 经过同样的流程,调用 ds_select_dst, 如果此时 B1 还是 INACTIVE ,那么就会直接找到 B2, 如果此时 B1 恢复了, 就会直接找到 B1 (因为 callid 一样)