环境是这样的:我们的网络上既有PC,也有思科VoIP电话。网络上有一个电话交换机,允许VoIP电话呼叫,但我认为该交换机与项目的这一部分无关。
这是我第一次在我的软件中加入VoIP,所以我想先让我的电脑给我的VoIP手机打个电话。从PC上,我可以ping电话的IP地址并获得响应,因此我应该能够与其通信。
到目前为止,我希望电话能开始响起。我在Java中使用mjsip,我收到一条呼叫失败的消息,原因是“请求超时”,并且没有振铃。我还没有做任何代码后会发生什么电话接听,但我想至少让它响起开始。
我希望有更多VoIP经验的人可以验证或排除我做这件事的不当之处,或者也许能够带来更多的陷阱。例如,仅仅因为它是一部VoIP电话,我就能期望它能响应sip呼叫吗?即使是同一网络中的VoIP电话,我也需要进行电话切换吗?只是我的代码有问题吗?
假设我做得很正确,代码正在启动一个sip堆栈,设置一个用户配置文件,并试图呼叫一个与手机IP和端口5060相对应的sip地址(Google告诉我sip端口通常是5060)。
public class SIPTest implements UserAgentListener, SipProviderListener
{
public static void main(String[] args)
{
if(!SipStack.isInit())
SipStack.init();
SipProvider sipProvider = new SipProvider("127.0.0.1", 5060);
UserAgentProfile profile = new UserAgentProfile();
profile.audio = true;
profile.hangup_time = 10;
profile.user = "testuser";
profile.keepalive_time = 8000;
final UserAgent userAgent = new UserAgent(sipProvider, profile, new SIPTest());
sipProvider.addPromiscuousListener(new SIPTest());
userAgent.call(new NameAddress(new SipURL("172.16.1.250", 5060)));
System.out.println("end ...");
}
/**
* begin SipProviderListener
**/
public void onReceivedMessage(SipProvider sip_provider,
Message message)
{
if (message.isInfo())
{
System.out.println("Promisque onReceivedMessage ... message " + message.getMethodId().toString() + "\n body = " + message.getBody());
}
}
/**
* end SipProviderListener
**/
/**
* begin UserAgentListener
**/
public void onUaCallAccepted(UserAgent arg0)
{
System.out.println("onUaCallAccepted ...");
}
public void onUaCallCancelled(UserAgent arg0)
{
System.out.println("onUaCallCancelled ...");
}
public void onUaCallClosed(UserAgent arg0)
{
System.out.println("onUaCallClosed ...");
}
public void onUaCallFailed(UserAgent arg0, String reason)
{
System.out.println("onUaCallFailed ...");
System.out.println("\t" + arg0);
System.out.println("\t" + reason);
}
public void onUaCallIncoming(UserAgent arg0,
NameAddress arg1, NameAddress arg2)
{
System.out.println("onUaCallIncoming ...");
System.out.println("from " + arg2.toString());
System.out.println("to " + arg1.toString());
arg0.accept();
System.out.println("Call accepted ...");
}
public void onUaCallProgress(UserAgent ua)
{
System.out.println("onUaCallProgress ...");
}
public void onUaCallRinging(UserAgent arg0)
{
System.out.println("onUaCallRinging ...");
}
public void onUaCallTransferred(UserAgent arg0)
{
System.out.println("onUaCallTrasferred ...");
}
public void onUaIncomingCall(UserAgent ua, NameAddress callee, NameAddress caller, Vector media_descs)
{
System.out.println("onUaIncomingCall ...");
}
public void onUaMediaSessionStarted(UserAgent ua, String type, String codec)
{
System.out.println("onUaMediaSessionStopped ...");
}
public void onUaMediaSessionStopped(UserAgent ua, String type)
{
System.out.println("onUaMediaSessionStopped ...");
}
public void onUaRegistrationFailed(UserAgent ua, String result)
{
System.out.println("onUaRegistrationFailed ...");
}
public void onUaRegistrationSucceeded(UserAgent ua, String result)
{
System.out.println("onUaRegistrationSucceeded ...");
}
/**
* end UserAgent
**/
}如果我运行它,下面是我得到的输出。
ExtendedAudioSystem: Supported: PCM_SIGNED PCM_UNSIGNED ALAW ULAW PCM_SIGNED PCM
_UNSIGNED PCM_FLOAT
ExtendedAudioSystem: TargetDataLine: PCM_SIGNED 8000.0 Hz, 16 bit, mono, 2 bytes
/frame, little-endian
ExtendedAudioSystem: Supported: PCM_SIGNED PCM_UNSIGNED ALAW ULAW PCM_SIGNED PCM
_UNSIGNED PCM_FLOAT
ExtendedAudioSystem: SourceDataLine: PCM_SIGNED 8000.0 Hz, 16 bit, mono, 2 bytes
/frame, little-endian
end ...
onUaCallFailed ...
local.ua.UserAgent@283bbb6
Request Timeout发布于 2013-11-27 22:45:32
在我看来,底层SIP INVITE消息(对应于userAgent.call)被认为是由sip堆栈发送的,但是没有接收到应答。因此,您会得到这个(408)“请求超时”消息。408请求超时是当没有从远程方(或代理)接收到响应时由SIP堆栈自动生成的sip响应。有时,出于一些奇怪的原因,防火墙可以阻止传出请求,并且不会通知java在发送数据包时发生了问题。因此,没有抛出异常,并且应用程序(这里是sip堆栈)不能再次发送分组,也不能通知用户网络问题。
您是否检查过可以使用同一主机上的另一个sip客户端调用sip:172.16.1.250?您可以使用sipp快速测试(使用选项-m 1仅启动一个呼叫)。如果您可以使用另一个sip客户端进行呼叫,则不存在防火墙问题。
https://stackoverflow.com/questions/16847748
复制相似问题