我应该在后台线程中调用 pjsua_call_make_call (pj::Call::makeCall) 吗?

Should I call pjsua_call_make_call (pj::Call::makeCall) in a background thread?

我正在开发具有自定义媒体传输的多帐户 SIP 软电话。我需要同时管理多个呼叫。我读过“PJSUA2 书”(3 PJSUA2-High Level API / General concepts / Asynchronous Operations):

(...) all operations that involve sending and receiving SIP messages are asynchronous, meaning that the function that invokes the operation will complete immediately (...) When this function [pj::Call::makeCall] returns successfully, it does not mean that the call has been established, but rather it means that the call has been initiated successfully. You will be given the report of the call progress and/or completion in the onCallState() callback method of Call class.

所以我想我可以调用 pj::Call::makeCall whenever/wherever 我需要发起一个调用,该函数几乎会立即 return 并且任何进展都会在回调方法中报告。但是今天在我的测试环境中,我注意到在我调用函数和它 returned 之间有几秒钟的延迟。下面是 makeCall 调用和 return 编辑之间出现的详细 PJSIP 日志。在“RTP socket reachable”之前可以看到将近 4s 的差距:

12:08:32.727           pjsua_call.c !Making call with acc #0 to sip:11@10.0.0.21:5060
12:08:32.727      dlg0x7f3a54002f08  .UAC dialog created
12:08:32.727      dlg0x7f3a54002f08  ..Session count inc to 2 by mod-pjsua
12:08:32.727          pjsua_media.c  .Call 0: initializing media..
12:08:36.069          pjsua_media.c  ..RTP socket reachable at 10.0.0.100:4000
12:08:36.069          pjsua_media.c  ..RTCP socket reachable at 10.0.0.100:4001
12:08:36.069     srtp0x7f3a540052d0  ..SRTP keying SDES created
12:08:36.069          pjsua_media.c  ..Media index 0 selected for audio call 0
12:08:36.069          pjsua_media.c  ..Call 0: media transport initialization complete: Success
12:08:36.069      dlg0x7f3a54002f08  ..Session count dec to 2 by mod-pjsua
12:08:36.069      dlg0x7f3a54002f08  .Module mod-invite added as dialog usage, data=0x7f3a5400d408
12:08:36.069      dlg0x7f3a54002f08  ..Session count inc to 4 by mod-invite
12:08:36.069      dlg0x7f3a54002f08  .Module mod-100rel added as dialog usage, data=0x7f3a5400f0a8
12:08:36.069      dlg0x7f3a54002f08  .100rel module attached
12:08:36.069      inv0x7f3a54002f08  .UAC invite session created for dialog dlg0x7f3a54002f08
12:08:36.069               endpoint  .Request msg INVITE/cseq=7778 (tdta0x7f3a5400f308) created.
12:08:36.069      inv0x7f3a54002f08  ..Sending Request msg INVITE/cseq=7778 (tdta0x7f3a5400f308)
12:08:36.069      dlg0x7f3a54002f08  ...Sending Request msg INVITE/cseq=7778 (tdta0x7f3a5400f308)
12:08:36.069      tsx0x7f3a54012278  ....Transaction created for Request msg INVITE/cseq=7777 (tdta0x7f3a5400f308)
12:08:36.069      tsx0x7f3a54012278  ...Sending Request msg INVITE/cseq=7777 (tdta0x7f3a5400f308) in state Null
12:08:36.069          sip_resolve.c  ....Target '10.0.0.21:5060' type=Unspecified resolved to '10.0.0.21:5060' type=UDP (UDP transport)
12:08:36.069      tsx0x7f3a54012278  ....State changed from Null to Calling, event=TX_MSG
12:08:36.070      dlg0x7f3a54002f08  .....Transaction tsx0x7f3a54012278 state changed to Calling
12:08:36.070            pjsua_acc.c !Sending 2 bytes keep-alive packet for acc 0 to 10.0.0.21:5060
12:08:36.070     tdta0x7f3a44005248  Destroying txdata raw
12:08:36.070            pjsua_acc.c  Sending 2 bytes keep-alive packet for acc 1 to 10.0.0.21:5060
12:08:36.070     tdta0x7f3a44005248  Destroying txdata raw

正常吗?我的意思是,我应该重新设计应用程序并在后台线程中调用 makeCall 吗?还是某些错误配置的结果?还是错误(某处)?

当我将 PJSIP 日志与带时间戳的 Wireshark 输出进行比较时,在我看来确实没有 SIP 数据包在 makeCall return 秒之前发送到 PBX。所以这几秒钟似乎浪费在内部 PJSIP 工作上。会不会是某些(临时)死锁的结果?

该应用程序在 64 位 Linux 上运行(在本例中为 Fedora 31 工作站)。

经过更多的研究,我可以回答我自己的问题。也许它可以帮助某人...

我发现 makeCall 触发了两次针对本地主机的 DNS 查询,每次查询都在将近 2 秒后失败。这将造成近 4 秒的差距。

解决方案是通过添加完全禁用本地主机 IP 地址解析 #define PJ_GETHOSTIP_DISABLE_LOCAL_RESOLUTION 1 进入 pjlib/include/pj/config_site.h 配置文件并重新编译 PJSIP 库。

这个问题原来是已知的,并且在 iOS 的情况下已经解决:https://trac.pjsip.org/repos/ticket/1342

有人在 Linux 上遇到了同样的问题:https://www.spinics.net/lists/pjsip/msg20517.html