拨打已​​注册(但离线)用户的问题 [英] Issue with dialing REGISTERED (but offline) users

查看:107
本文介绍了拨打已​​注册(但离线)用户的问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我面临以下情况: 我们必须向本地(注册)用户(iOS应用程序pjSIP)发起相互之间的本地呼叫. 当其中一个用户(例如用户B)在成功注册后几分钟关闭应用程序时,就会出现此问题. 现在,当用户A尝试呼叫用户B时,我们看到发送了邀请,但没有收到用户B的回复(例如180振铃).

i'm facing the following scenario: we have to local (REGISTERED) users (iOS apps pjSIP) which initiating local calls between each other. the problem arise when one of the users (let's say user B) is closing the application few minutes after he successfully REGISTERS. now, when user A tries to call user B we see that the INVITE is sent but we got no reply (e.g 180 ringing) from User B.

注意:当我们向用户B发送邀请时,他会收到推送通知到他的设备,这会导致他打开应用程序(并重新注册)

Note: when we are sending an invite to User B he get's Push notification to his device what cases him to open the app (and to Re-REGISTER)

我们的目标是: 1.在用户B应用已关闭且其扩展名仍在注册的情况下,在发送邀请之前确定用户B(例如被叫方)是否可访问 2.能够在用户B注册后立即向他发送邀请

our targets are: 1. determinate if user B (e.g the callee) is reachable before we are sending an INVITE in cases User B App is closed and his extension is still REGISTERED 2. be able to send invite to user B right after he REGISTER

我们尝试从多个方向解决此问题: 1.Qualify-尝试减少注册期间的合格时间,以便用户B将尽快变为不可用"(并且我们将在拨号前检查设备状态),但这可能会导致网络上出现大量OPTIONS,并且不会解决目标#2 2.AMI服务-它可以捕获以下事件:用户A拨打用户B,用户B正在振铃(180振铃)并将这些状态保存到ASTDB.所有这些逻辑将在启动拨盘之前预先设定. 该解决方案笨拙且复杂,需要观看其他服务

we tried to solve this issue from many directions: 1.Qualify - tried to decrease the qualify time of the registersion period so user B will be UNAVAILABLE as soon as possible (and we will check the device state before we will dial) but it may cause to massive OPTIONS on our network, and it's not going to solve target #2 2.AMI Service - it can catch events like: User A Dials user B , User B is Ringing (180 Ringing) and save those statuses to ASTDB . all this logic will be prefomed before we will launch the dial. this solution is clumsy and to cmplicated and it requires to watch yet another service

经过一些研究,我得出的结论是,最合适的解决方案是存储每个扩展名的最后OPTIONS答复的时间(在chan_sip.c中需要一个补丁).在用户A拨打之前,重新触发Sip选项会限制对用户B的请求.如果原始值(例如,在我们重新触发OPTIONS之前)等于在我们触发OPTIONS之后的值,则表明用户B尚未回复OPTIONS.

after some research i'v got to the conclusion that the most suitable solution will be to store the time of the last OPTIONS reply of each extension(requires a patch in chan_sip.c) . re-trigger sip options qualify request to user B before User A Dials . if the original value (e.g before we re-triggered the OPTIONS) is equal the value after we trigged the OPTIONS it means that User B has not replied OPTIONS.

我将附加为完成此任务而执行的更改. 我想知道解决该问题的方法是否合适和有效,当然还有更好的方法来解决这个问题.

i'm attaching the changes i'v preformed to complete this task. i would like to know if solution for the issue is suitable and valid and of course if there is a better way to preform it.

这些是chan_sip中的更改(使用星号11.7) 我仅在以下几行中预先进行了更改: 23492至23500

These is the change in chan_sip (using asterisk 11.7) i'v prefomed changes only on the following lines: 23492 to 23500

  23485 /*! \brief Handle qualification responses (OPTIONS) */
  23486 static void handle_response_peerpoke(struct sip_pvt *p, int resp, struct sip_request *req)
  23487 {
  23488   struct sip_peer *peer = /* sip_ref_peer( */ p->relatedpeer /* , "bump refcount on p, as it is being used in this function(handle_response_peerpoke)")*/ ; /* hope this is already refcounted! */
  23489   int statechanged, is_reachable, was_reachable;
  23490   int pingtime = ast_tvdiff_ms(ast_tvnow(), peer->ps);
  23491
  23492   time_t result = time(NULL);
  23493   result = (int)result;

这是应如何使用补丁实施拨号计划:

This is how should implement dialplan with the patch:

Dial(SIP/${dest},10,Rgb(check_extension,s,1));

I'm sending the call to context before inviting ( with the "b" option)
context check_extension {
  s => {
    Set(IS_REACHABLE=0);
    Verbose(KOLA/LastQualify/${DEST}); // Display User B initial quliafy
    Set(INITIAL_QUALIFY=${DB(KOLA/LastQualify/${DEST})}); // Store it
    for(loop=0;${loop}<60;dialLoop=${loop}+1) { // Loop untill the qualify will be changes
      System(/usr/sbin/asterisk -rx "sip qualify peer ${DEST}");
      Wait(2); // we need to wait a while for a response
      Set(LAST_QUALIFY=${DB(KOLA/LastQualify/${DEST})}); // set the new qualify
      if (${LAST_QUALIFY} > ${INITIAL_QUALIFY}) { // if the new qualify is newer, User B is reachable
        Set(IS_REACHABLE=1);
        break;
      }
    }

    if (${IS_REACHABLE} = 0) {
      Verbose(Peer is not reachable);
      Hangup();
    }
  }
}

推荐答案

最佳选择是不使用星号.

Best option for that is not use asterisk.

使用kamailio或opensips项目,它可以处理数千个选项包.

Use kamailio or opensips project, it can handle thousands of options packets.

您还必须重写您的应用程序,以便在其关闭时 UNREGISTER ,如sip RFC中所述.

Also you HAVE rewrite your app so when it closed it UNREGISTER, as that described in sip RFC.

总结:您正在使用错误的应用程序,并且尝试对它不打算使用的星号进行操作(大量用户具有选项).因此,正确的答案-为此任务使用正确的工具.

To summarize: you are using buggy application, and triing do on asterisk thing it not designed to(large amount of users with options). So correct answer - use correct tools for this task.

这篇关于拨打已​​注册(但离线)用户的问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆