我写了一个SIP UAC,我尝试了几种方法来检测和忽略来自UAS的重复传入消息,但是我尝试的每一种方法都出错了,我的问题是所有的消息都有与同一个调用具有相同的签名,并且比较所有的消息文本太多了,所以我想知道,在尝试检测这些重复消息时,我应该查看构成消息的参数。
更新
我遇到了传入的选项问题,我通过向服务器发送一个空的Ok响应来处理。 (更新:经过一段时间的测试后,我注意到,我仍然得到了所有,然后我得到另一个选项请求,每隔几秒就有几个,所以我尝试使用Bad请求进行响应,现在我只获得一次/两次选项请求每次注册/重新注册)
目前我有重复SessionInPogress的消息,以及不同的错误消息,例如忙碌,不可用,我得到了很多这些,并且它会让我的日志混乱,我想过滤它们。
任何想法如何实现?
更新
我会在发回之前尝试你的技术,也许这会解决我的问题
这是我使用的,它很好用:
private boolean compare(SIPMessage message1, SIPMessage message2) {
if (message1.getClass() != message2.getClass())
return false;
if (message1.getCSeq().getSeqNumber() != message2.getCSeq().getSeqNumber())
return false;
if (!message1.getCSeq().getMethod().equals(message2.getCSeq().getMethod()))
return false;
if (!message1.getCallId().equals(message2.getCallId()))
return false;
if (message1.getClass()==SIPResponse.class)
if(((SIPResponse)message1).getStatusCode()!=((SIPResponse)message2).getStatusCode())
return false;
return true;
}
谢谢, 亚当。
答案 0 :(得分:2)
这比ChrisW的回答要复杂一点。
首先,事务层过滤掉大多数重传。在大多数情况下,它通过将收到的消息与当前事务列表进行比较来实现此目的。如果找到了一个事务,那么该事务将主要根据RFC 3261, section 17中的图表吞下重传。例如,Proceeding状态中的UAC INVITE事务将丢弃延迟重传的INVITE。
匹配以两种方式之一进行,具体取决于远程堆栈。如果它是RFC 3261堆栈(最顶层Via的分支参数以“z9hG4bK”开头),那么事情就相当简单了。 Section 17.2.3涵盖了全部细节。
这样的匹配将过滤掉重复/重新传输的OPTIONS(您提到的特定问题)。 OPTIONS消息不会形成对话框,因此查看CSeq将无法正常工作。特别是,如果UAS发出五个不仅仅是重传的OPTIONS请求,您将获得五个OPTIONS请求(以及五个非INVITE服务器事务)。
对非INVITE事务的重新传输的临时响应被传递到Transaction-User层,或者有时被称为核心,但除了第一个之外,最终响应不是。 (同样,您只需通过为该事务实现FSM即可实现此目的 - 最终响应将UAC非INVITE事务置于已完成状态,这将丢弃任何进一步的响应。
之后,Transaction-User层通常会收到INVITE事务的多个响应。
UAS发送多个183s是完全正常的,至少对于INVITE来说是这样。例如,它可能会立即发送100来熄灭您的重传(至少通过不可靠的传输),然后是几个183,一个180,可能多一些183,最后一个200(或更多,对于不可靠的传输)。
交易层提交所有这些响应非常重要,因为代理和用户代理以不同方式处理响应。
在此级别,响应不会在某种程度上重新传输。我应该说:UAS不使用重传逻辑来发送大量临时响应(除非它实现RFC 3262)。重新发送200 OKs到INVITE,因为它们会破坏UAC事务。您可以通过及时发送您的ACK来避免重新传输。
答案 1 :(得分:0)
我认为消息是重复/相同的,如果它...
...值与另一条消息的值匹配。
请注意,响应消息与其响应的请求具有相同的CSeq;并且,单个请求可以获得多个临时但非重复的响应(例如RINGING后跟OK)。