SIP/HTTP融合应用INVITE请求无法向外发送问题咨询
首先明确:这不是你的操作失误,而是Mobicents SIP Servlet容器(以及WAS Liberty上的SIP容器实现)的默认路由行为,和SIP 1.1规范本身没有直接关系。
为什么INVITE会被本地Sip Servlet接收?
当你在同一个Web应用内通过SipFactory创建SIP INVITE并调用request.send()时,容器会优先检查本地是否有匹配的Sip Servlet(不管是通过@SipServlet注解还是sip.xml里的映射规则)。如果存在能匹配该INVITE请求的Sip Servlet,容器就会把请求路由到本地的Servlet实例,而不是直接通过网络发送到目标地址。
这种设计是为了让同一个应用内的HTTP组件和SIP组件能无缝协作,简化信令的处理流程。
对比Click-to-Call示例的差异
你提到的示例能正常发送请求,核心原因是它的Sip Servlet里实现了代理转发逻辑:当doInvite()方法收到本地路由过来的INVITE后,会调用SIP代理API(比如request.getProxy().proxyTo(targetURI))将请求转发到真正的目标SIP地址。示例里的sip.xml和web.xml主要是用来配置Servlet的映射规则、会话超时等,而真正让请求发往网络的是Sip Servlet里的代理代码。
解决方案
根据你的需求,有两种处理方式:
- 直接发送到网络:调整本地Sip Servlet的路由规则,让它不匹配你从Web Servlet发送的INVITE请求(比如修改
@SipServlet的mapping属性,或者sip.xml里的<servlet-mapping>),这样容器就会跳过本地路由,直接将请求发往网络。 - 遵循规范分层模式:参考示例的设计,让Web Servlet仅负责触发SIP请求,而Sip Servlet负责处理信令的路由、会话管理等逻辑。这种方式更符合SIP Servlet规范的设计理念,也便于后续扩展复杂的SIP交互流程。
关于SIP 1.1规范的说明
SIP 1.1规范并没有规定HTTP Servlet发送的INVITE必须被本地Sip Servlet接收,这完全是容器的实现行为。Mobicents和WAS Liberty的SIP容器都采用了这种本地优先的路由策略,来简化同应用内的组件交互。
内容的提问来源于stack exchange,提问作者Shahed

