2

我写了一个 SIP UAC,我尝试了几种方法来检测和忽略来自 UAS 的重复传入消息,但是在我尝试的每一种方法中,都出现了问题,我的问题是所有与相同的调用具有相同的签名,并且比较所有消息文本太多了,所以我想知道,在尝试检测这些重复消息时,我应该查看构成消息的哪个参数。

更新:

我遇到了传入选项的问题,我通过向服务器发送一个空的 Ok 响应来处理这个问题。(更新:经过一段时间的测试,我注意到,我仍然时不时地收到另一个选项请求,每隔几秒就很少,所以我尝试用错误的请求进行响应,现在我只收到一次/两次选项请求每次注册/重新注册)

目前我有重复的 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;
}

谢谢,亚当。

4

2 回答 2

2

这比 ChrisW 的回答要复杂一些。

首先,事务层过滤掉大部分重传。在大多数情况下,它通过将接收到的消息与当前事务列表进行比较来做到这一点。如果找到一个事务,该事务将根据RFC 3261 第 17 节中的图表大部分吞下重传。例如,处于 Proceeding 状态的 UAC INVITE 事务将丢弃延迟重传的 INVITE。

匹配以两种方式之一进行,具体取决于远程堆栈。如果它是一个 RFC 3261 堆栈(最上面的 Via 上的分支参数以“z9hG4bK”开头),那么事情就相当简单了。第 17.2.3 节涵盖了全部细节。

像这样的匹配将过滤掉重复/重新传输的 OPTIONS(您提到的特定问题)。OPTIONS 消息不会形成对话框,因此查看 CSeq 将不起作用。特别是,如果 UAS 发出 5 个 OPTIONS 请求而不仅仅是重传,您将收到 5 个 OPTIONS 请求(以及 5 个非 INVITE 服务器事务)。

对非 INVITE 事务重新传输的临时响应被传递到事务用户层,或者有时称为核心,但除了第一个,最终响应不是。(同样,您只需为该事务实施 FSM 即可获得此结果 - 最终响应将 UAC 非邀请事务置于已完成状态,这会丢弃任何进一步的响应。

之后,Transaction-User 层通常会收到 INVITE 事务的多个响应。

UAS 发送多个 183 是完全正常的,至少对于 INVITE 来说是这样。例如,它可能会立即发送一个 100 来终止您的重传(至少通过不可靠的传输),然后是几个 183,一个 180,可能更多的 183,最后是一个 200(或更多,对于不可靠的传输)。

事务层处理所有这些响应很重要,因为代理和用户代理处理响应的方式不同。

在这个级别上,响应在某种程度上不会被重新传输。我应该说:UAS 不使用重传逻辑来发送大量临时响应(除非它实现RFC 3262)。200 对 INVITE 的 OK 被重新发送,因为它们破坏了 UAC 事务。您可以通过及时发送 ACK 来避免它们的重传。

于 2010-07-01T16:18:00.273 回答
0

我认为一条消息是重复/相同的,如果它......

  • Cseq
  • 来电显示
  • 和方法名称(例如“INVITE”)

...值与另一条消息的值匹配。

请注意,响应消息具有与其响应的请求相同的 CSeq;并且,单个请求您会得到多个临时但不重复的响应(例如 RINGING 后跟 OK)。

于 2010-07-01T11:08:29.640 回答