SIP 简介

原文来自 Kamailio Site,绝大部分是自动翻译的,少量改动和注释。1. SIP Introduction​www.kamailio.org/docs/tutorials/sip-introduction/

SIP简介

简· 贾纳克(Jan Janak)<[email protected]>版权所有©2003 FhG FOKUS

摘要SIP的简要概述,描述了SIP的所有重要方面。

SIP的目的

SIP代表会话启动协议。它是在IETF中开发和设计的应用程序层控制协议。该协议在设计时考虑到易于实现,良好的可伸缩性和灵活性。

该规范以几种RFC的形式提供,其中最重要的是包含核心协议规范的RFC3261。该协议用于创建,修改和终止与一个或多个参与者的会话。通过会话,我们了解了一组进行通信的发送方和接收方,以及在通信过程中这些发送方和接收方保持的状态。会话的示例可以包括Internet电话呼叫,多媒体分发,多媒体会议,分布式计算机游戏等。

SIP不是通信设备将需要的唯一协议,也不意味着是通用协议。SIP的目的仅仅是使通信成为可能,通信本身必须通过其他方式(可能还有其他协议)来实现。与SIP一起最常使用的两种协议是RTP和SDP。 RTP协议用于承载实时多媒体数据(包括音频,视频和文本),该协议可以将数据编码和拆分为数据包,并通过Internet传输此类数据包。 另一个重要的协议是SDP,用于描述和编码会话参与者的功能。 然后,将这种描述用于协商会话的特征,以便所有设备都可以参与(例如,包括协商用于编码媒体的编解码器,以便所有参与者都可以对其进行解码,协商使用的传输协议 等等)。

值得一提的是,SIP的端到端概念与常规PSTN(公共交换电话网络)存在显着差异,在常规PSTN中,所有状态和逻辑都存储在网络中,而终端设备(电话)非常原始。SIP的目的是提供与传统PSTN相同的功能,但是端到端设计使SIP网络更加强大,并且对实现传统PSTN中难以实现的新服务开放。

SIP基于HTTP协议。HTTP协议从RFC822继承了邮件头的格式。HTTP可能是Internet中最成功且使用最广泛的协议。它试图将两者的优点结合在一起。实际上,HTTP也可以归类为信令协议,因为用户代理使用该协议告诉HTTP服务器他们对哪些文档感兴趣。SIP用于承载会话参数的描述,该描述被编码到文档中使用SDP。两种协议(HTTP和SIP)都从RFC822继承了消息头的编码。多年来,编码被证明是健壮和灵活的。

SIP URI

使用SIP URI(统一资源标识符)识别SIP实体。SIP URI的格式为sip:username @ domain,例如sip:[email protected]。如我们所见,SIP URI由用@(@)字符分隔的用户名部分和域名部分组成。SIP URI与电子邮件地址类似,例如,可以将相同的URI用于电子邮件和SIP通信,这样的URI易于记住。

SIP网络元素

尽管在最简单的配置中,可以仅使用两个直接相互发送SIP消息的用户代理,但是典型的SIP网络将包含不止一种类型的SIP元素。SIP的基本元素是用户代理,代理,注册商和重定向服务器。我们将在本节中简要描述它们。

请注意,本节介绍的元素通常只是逻辑实体。将它们放置在一起通常是有利的,例如,提高处理速度,但这取决于特定的实现和配置。

用户代理

使用SIP相互查找并协商会话特征的Internet端点称为用户代理。用户代理通常(但不是必须)以应用程序的形式驻留在用户计算机上-这是目前使用最广泛的方法,但是用户代理也可以是蜂窝电话,PSTN网关,PDA,自动 IVR系统等。

用户代理通常称为用户代理服务器 (UAS)和用户代理客户端(UAC)。UAS和UAC只是逻辑实体,每个用户代理都包含一个UAC和UAS。UAC是用户代理中发送请求和接收响应的部分。UAS是用户代理的一部分,它接收请求并发送响应。

由于用户代理同时包含UAC和UAS,因此我们经常说用户代理的行为类似于UAC或UAS。例如,呼叫者的用户代理在发送INVITE请求并接收对该请求的响应时,其行为类似于UAC。被叫方的用户代理在收到INVITE并发送响应时的行为类似于UAS。

但是,当被叫方决定发送BYE并终止会话时,这种情况就会改变。在这种情况下,被呼叫者的用户代理(发送BYE)的行为类似于UAC,而呼叫者的用户代理的行为类似于UAS。

图1. UAC和UAS

上图显示了三个用户代理和一个有状态分支代理。每个用户代理均包含UAC和UAS。实际上,从呼叫者接收INVITE的代理部分充当了UAS。当有状态转发请求时,代理会创建两个UAC,每个UAC负责一个分支。在我们的示例中,被叫方B接听电话,然后当他想断开呼叫时,它会发送BYE。此时,以前是UAS的用户代理变成了UAC,反之亦然。

代理服务器

除此之外,SIP还允许创建称为代理服务器的网络主机的基础结构。用户代理可以将消息发送到代理服务器。代理服务器是SIP基础结构中非常重要的实体。他们根据被邀请者的当前位置,身份验证,记帐和许多其他重要功能来执行会话邀请的路由。代理服务器最重要的任务是将会话邀请“更近”地路由到被叫方。会话邀请通常会遍历一组代理,直到找到知道被呼叫者实际位置的代理为止。这样的代理将会话邀请直接转发给被呼叫者,然后被呼叫者将接受或拒绝会话邀请。SIP代理服务器有两种基本类型:无状态和有状态。

无状态服务器

无状态服务器是简单的消息转发器。它们彼此独立地转发消息。尽管通常将消息安排在事务中(请参见第1.5节“ SIP事务”),但无状态代理不会处理事务。无状态代理很简单,但是比有状态代理服务器快。它们可以用作简单的负载平衡器,消息转换器和路由器。无状态代理的缺点之一是它们无法吸收消息的重传并无法执行更高级的路由,例如派生或递归遍历。

有状态服务器

有状态代理更为复杂。收到请求后,有状态代理会创建一个状态并保留该状态,直到事务完成。某些交易,特别是由INVITE创建的交易,可以持续很长时间(直到被叫方接听或拒绝电话)。因为有状态代理必须在事务期间保持状态,所以它们的性能受到限制。将SIP消息关联到事务中的能力为状态代理提供了一些有趣的功能。有状态代理可以执行派生,这意味着在接收到一条消息后,将发送两条或更多条消息。有状态代理可以吸收重传,因为它们从事务状态中知道是否已经接收到相同的消息(无状态代理无法进行检查,因为它们不保留任何状态)。有状态代理可以执行更复杂的查找用户的方法。例如,可以尝试拨打用户的办公室电话,而当他不接听电话时,呼叫将被转接到他的手机。无状态代理无法做到这一点,因为它们无法知道针对办公电话的交易是如何完成的。如今,大多数SIP代理都是有状态的,因为它们的配置通常非常复杂。他们通常执行记帐,分叉,某种形式的NAT遍历帮助,并且所有这些功能都需要有状态代理。

代理服务器使用典型的配置是每个集中管理的实体(例如,一家公司)都有其自己的SIP代理服务器,该实体中的所有用户代理都使用该服务器。假设有两家公司A和B,它们各自都有自己的代理服务器。图2“会话邀请” 显示了公司A中的员工Joe的会话邀请将如何到达公司B中的Bob的会话。图2.会话邀请

用户Joe使用地址sip:[email protected]呼叫Bob。Joe的用户代理不知道如何自行路由邀请,但已配置为将所有出站流量发送到公司SIP代理服务器http://proxy.a.com。代理服务器发现用户sip:[email protected]在另一家公司,因此它将查找B的SIP代理服务器并将邀请发送到该服务器。可以在http://proxy.a.com上预先配置B的代理服务器,或者该代理将使用 DNS SRV记录来查找B的代理服务器。邀请到达http://proxy.bo.com。代理知道鲍勃当前正坐在他的办公室中,并且可以通过IP地址1.2.3.4的桌子上的电话与他联系,因此代理将向该地址发送邀请。

注册器我们提到过http://proxy.b.com上的SIP代理知道当前Bob的位置,但尚未提及代理如何学习用户的当前位置。Bob的用户代理(SIP电话)必须在注册 商处注册。注册服务商是一个特殊的SIP实体,它接收用户的注册,提取有关其当前位置的信息(在这种情况下为IP地址,端口和用户名),并将该信息存储到位置数据库中。位置数据库的目的是将sip:[email protected]映射到类似sip:[email protected]:5060的位置。然后,位置数据库由B的代理服务器使用。当代理收到sip:[email protected]的邀请时,它将搜索位置数据库。它找到sip:[email protected]:5060并将邀请发送到那里。注册服务商通常只是逻辑实体。由于它们与代理注册商紧密耦合,因此通常与代理服务器位于同一位置。图3“注册器概述”显示了典型的SIP注册。包含记录地址sip:[email protected]和联系地址sip:[email protected]:5060的REGISTER消息(其中1.2.3.4是电话的IP地址)被发送到注册商。注册服务商提取此信息并将其存储到位置数据库中。如果一切顺利,则注册服务商会向电话发送200 OK响应,注册过程完成。图3.注册器概述

每次注册都有有限的寿命。Expires标头字段或Contact标头字段的expires参数确定注册有效的时间。用户代理必须在有效期内刷新注册,否则注册将过期并且用户将不可用。

重定向服务器接收请求并发回包含特定用户当前位置列表的回复的实体称为重定向服务器。重定向服务器接收请求,并在注册服务商创建的位置数据库中查找请求的预期收件人。然后,它创建用户当前位置的列表,并将其发送到3xx类内的响应中的请求发起者。然后,请求的发起者提取目的地列表,并将另一个请求直接发送给目的地。图4“ SIP重定向”显示了典型的重定向。图4. SIP重定向

SIP消息

使用SIP的通信(通常称为信令)包括一系列 消息。消息可以由网络独立传输。通常,它们各自在单独的UDP数据报中传输。每条消息均由“第一行”,消息头和消息正文组成。第一行标识消息的类型。消息有两种类型:request和response。请求通常用于启动某些操作或将某些请求通知接收者。答复用于确认已接收并处理了请求,并包含处理的状态。

典型的SIP请求如下所示:

INVITE sip:[email protected] SIP/2.0Via: SIP/2.0/UDP 195.37.77.100:5040;rportMax-Forwards: 10From: "jiri" <sip:[email protected]>;tag=76ff7a07-c091-4192-84a0-d56e91fe104fTo: <sip:[email protected]>Call-ID: [email protected]: 2 INVITEContact: <sip:213.20.128.35:9315>User-Agent: Windows RTC/1.0Proxy-Authorization: Digest username="jiri", realm="http://iptel.org", algorithm="MD5", uri="sip:[email protected]", nonce="3ceff5ae1b8b7f0d742da1feb5753c", response="53fe98db10e1074 b03b3e06438bda70f"Content-Type: application/sdpContent-Length: 451v=0o=jku2 0 0 IN IP4 213.20.128.35s=sessionc=IN IP4 213.20.128.35b=CT:1000t=0 0m=audio 54742 RTP/AVP 97 111 112 6 0 8 4 5 3 101a=rtpmap:97 red/8000a=rtpmap:111 SIREN/16000a=fmtp:111 bitrate=16000a=rtpmap:112 G7221/16000a=fmtp:112 bitrate=24000a=rtpmap:6 DVI4/16000a=rtpmap:0 PCMU/8000a=rtpmap:4 G723/8000a=rtpmap: 3 GSM/8000a=rtpmap:101 telephone-event/8000a=fmtp:101 0-16

第一行告诉我们这是INVITE消息,用于建立会话。第一行的sip:[email protected]上的URI称为请求URI,其中包含消息下一跳的URI。在这种情况下,它将是主机http://iptel.org。

一个SIP请求可以包含一个或多个Via头字段,用于记录请求的路径。它们随后用于完全相同的路由SIP响应。INVITE消息仅包含一个Via标头字段,该字段由发送请求的用户代理创建。从“Via”字段,我们可以知道用户代理正在主机195.37.77.100和端口5060上运行。

从和到标头字段标识邀请的发起者(呼叫者)和接收者(被呼叫者)(就像在SMTP中一样,它们标识消息的发送者和接收者)。From字段包含一个标签参数,该标签参数用作对话框标识符。

呼叫ID头字段是一个对话框标识符,其目的是识别属于同一呼叫的消息。这样的消息具有相同的呼叫ID标识符。CSeq用于维护请求的顺序。因为可以通过不可靠的传输来发送请求,从而可以对消息进行重新排序,所以消息中必须存在序列号,以便收件人可以识别重新传输和混乱的请求。

Contact字段包含IP地址和端口,发送方在该IP地址和端口上等待被呼叫方发送的其他请求。其他标题字段并不重要,在此将不进行描述。邮件标题由邮件正文用空行分隔。INVITE请求的消息正文包含对发送者接受并以SDP编码的媒体类型的描述。

SIP请求我们已经描述了INVITE请求的外观,并说该请求用于邀请被调用方加入会话。其他重要要求是:

ACK-此消息确认收到对INVITE的最终响应。由于邀请的不对称性质,建立会话使用了三向握手。被叫方接受或拒绝呼叫可能需要一段时间,因此被叫方的用户代理会定期重新发送肯定的最终响应,直到接收到ACK(表明呼叫方仍在并准备进行通信)为止。BYE --Bye消息被用来结束多媒体会话。希望取消会话的一方将BYE发送给另一方。取消-取消用于取消尚未完全建立的会话。当被呼叫者尚未答复最终答复但呼叫者想中止呼叫时(通常是当被呼叫者一段时间未响应时),将使用它。REGISTER -REGISTER请求的目的是让注册商知道当前用户的位置。REGISTER消息中包含有关可访问用户的当前IP地址和端口的信息。注册器提取此信息并将其放入位置数据库。SIP代理服务器以后可以使用该数据库将呼叫路由到用户。注册是有时间限制的,需要定期刷新。

列出的请求通常没有消息正文,因为在大多数情况下不需要(但可以有一个)。除此以外,还定义了许多其他请求类型,但是它们的描述超出了本文档的范围。

SIP回应当用户代理或代理服务器收到请求时,它将发送答复。除ACK请求不会触发答复外,每个请求都必须得到答复。典型的回复如下所示:

SIP/2.0 200 OKVia: SIP/2.0/UDP 192.168.1.30:5060;received=66.87.48.68From: sip:[email protected]: sip:[email protected];tag=794fe65c16edfdf45da4fc39a5d2867c.b713Call-ID: @192.168.1.30CSeq: 63629 REGISTERContact: Msip:[email protected]:5060;transport=udp>;q=0.00;expires=120Server: Sip EXpress router (0.8.11pre21xrc (i386/linux))Content-Length: 0Warning: 392 195.37.77.101:5060 "Noisy feedback tells:pid=5110 req_src_ip=66.87.48.68 req_src_port=5060 in_uri=sip:http://iptel.org out_uri=sip:http://iptel.org via_cnt==1"

如我们所见,除了第一行之外,响应与请求非常相似。响应的第一行包含协议版本(SIP / 2.0),回复代码和原因短语。

所述应答代码是从100到699的整数,并表示响应的类型。有6类回复:

1xx是临时 响应。临时响应是一种响应,它告诉其接收者已接收到关联的请求,但处理结果尚不清楚。仅在处理未立即完成时才发送临时响应。发送者必须在收到临时响应后停止重新发送请求。通常,代理服务器在开始处理INVITE时会发送代码为100的响应,而用户代理会发送代码为180(振铃)的响应,这表示被叫方的电话正在振铃。2xx回应为肯定的最终回应。最终响应是请求的发起者将收到的最终响应。因此,最终响应表示关联请求的处理结果。最终响应也会终止交易。代码从200到299的响应均为肯定响应,这表示请求已成功处理并被接受。例如,当用户接受会话邀请(INVITE请求)时,将发送200 OK响应。一个UAC可能会收到200条针对单个INVITE请求的消息。这是因为派生代理(稍后描述)可以派生该请求,因此它将到达多个UAS,并且每个UAS都将接受邀请。在这种情况下,每个响应都由“收件人”头字段中的tag参数来区分。每个响应代表一个具有明确对话框标识符的独特对话框。3xx响应用于重定向呼叫者。重定向响应提供有关用户的新位置或呼叫者可能用来满足呼叫的替代服务的信息。重定向响应通常由代理服务器发送。当代理收到请求并且由于任何原因不希望或无法处理该请求时,它将发送重定向响应给调用方,并将另一个位置放入响应中,调用方可能要尝试。它可以是另一个代理的位置,也可以是被叫方的当前位置(来自注册商创建的位置数据库)。然后,呼叫者应将请求重新发送到新位置。3xx的答复为最终答复。4xx是负面的最终 回应。4xx响应表示问题出在发件人一方。该请求包含错误的语法或无法在该服务器上满足,因此无法处理。5xx表示问题出在服务器端。该请求显然有效,但服务器无法满足该请求。客户通常应稍后重试该请求。6xx回复代码表示该请求无法在任何服务器上得到满足。此响应通常由具有有关特定用户的确定信息的服务器发送。当用户不想参加会话时,用户代理通常会发送603拒绝响应。

除了响应类,第一行还包含原因短语。该代码号旨在由机器处理,它不是很人性化,但是很容易由机器解析和理解。原因短语通常包含描述处理结果的可读消息。用户代理应将原因短语呈现给用户。使用CSeq标头字段标识特定响应所属的请求。除了序列号之外,此标头字段还包含相应请求的方法。在我们的示例中,这是REGISTER请求。

SIP事务 (SIP TRANSACTION)

尽管我们说过SIP消息是通过网络独立发送的,但是它们通常由用户代理和某些类型的代理服务器安排在事务中。因此,SIP被认为是一种 事务性协议。事务是在SIP网络元素之间交换的一系列SIP消息。事务由一个请求和对该请求的所有响应组成。其中包括零个或多个临时响应和一个或多个最终响应(请记住,当代理服务器派生请求时,INVITE可能会被多个最终响应所应答)。如果事务是由INVITE请求发起的,则同一事务还包括ACK,但前提是最终响应不是2xx响应。如果最终响应是2xx响应,则ACK不被视为事务的一部分。如我们所见,这是非常不对称的行为-ACK是最终响应为负的事务的一部分,但不是最终响应为正的事务的一部分。分离的原因是传递所有200条OK消息的重要性。当代理服务器派生请求,并且所有实体都必须传递给主叫用户代理时,不仅它们建立了会话,而且多个实体还可以生成200 OK。因此,用户代理在这种情况下负责并重新发送200 OK响应,直到他们收到ACK。另请注意,仅对INVITE的响应会重新发送!具有事务处理概念的SIP实体称为 有状态的。这样的实体通常创建与交易相关联的状态,该状态在交易期间一直保存在内存中。当请求或响应到来时,有状态实体会尝试将请求(或响应)与现有事务相关联。为了做到这一点,它必须从消息中提取一个唯一的交易标识符,并将其与所有现有交易的标识符进行比较。如果存在这样的事务,则从消息中更新其状态。在以前的SIP RFC2543中,交易标识符被计算为所有重要消息头字段(包括To,From,Request-URI和CSeq)的哈希值。在互操作性测试期间,这被证明是非常缓慢且复杂的,这种事务标识符曾经是问题的常见根源。在新的RFC3261中,完全改变了计算交易标识符的方式。现在,SIP消息不再包含重要标头字段的复杂散列,而是直接包含标识符。Via标头字段的Branch参数直接包含交易标识符。这是极大的简化,但是仍然存在不支持事务标识符新计算方式的旧实现,因此即使新实现也必须支持旧方法。它们必须向后兼容。图5“ SIP事务”显示了在两个用户代理进行对话期间哪些消息属于哪些事务。图5. SIP事务

SIP对话 (DIALOG)

我们已经说明了什么是事务,其中一个事务包括INVITE及其响应,而另一事务包括BYE,并且它在会话断开时响应。但是我们认为这两个事务应该以某种方式关联-它们都属于同一个对话。对话框表示两个用户代理之间的对等SIP关系。对话会持续一段时间,这对于用户代理来说是非常重要的概念。对话有助于在SIP端点之间正确排序和路由消息。

对话是使用Call-ID,From标签和To标签来标识的。具有这三个标识符相同的消息属于同一对话。我们已经展示了CSeq标头字段用于对消息进行排序,实际上,它用于对对话中的消息进行排序。对话中发送的每个消息的数量必须单调增加,否则对等方将按无序请求或重新传输的方式处理该消息。实际上,CSeq编号标识对话中的事务,因为我们已经说过,请求和相关的响应称为事务。这意味着在一个对话中每个方向上只能进行一个事务。人们还可以说对话是一系列事务。图6,“ SIP对话”扩展了图5“ SIP事务”以显示哪些消息属于同一对话。图6. SIP对话

有些消息会建立一个对话,有些则不会。这允许显式表达消息的关系,也可以在对话外发送与其他消息不相关的消息。这很容易实现,因为用户代理不必保持对话状态。例如,INVITE消息建立了一个对话,因为稍后它将跟随BYE请求,该请求将拆除INVITE建立的会话。该BYE在INVITE建立的对话中发送。但是,如果用户代理发送MESSAGE请求,则该请求不会建立任何对话。任何后续的消息(甚至MESSAGE)将独立于前一个发送。1.6.1。对话有助于路由我们已经说过,对话还用于在用户代理之间路由消息,让我们对此进行一些描述。假设用户sip:[email protected]想与用户sip:[email protected]对话。他知道被叫方的SIP地址(sip:[email protected]),但是该地址没有说明用户的当前位置,即,呼叫方不知道向哪个主机发送请求。因此,INVITE请求将被发送到代理服务器。该请求将从一个代理服务器发送到另一个代理服务器,直到到达知道被叫方当前位置的请求为止。此过程称为路由。一旦请求到达被叫方,被叫方的用户代理将创建一个响应,并将其发送回给呼叫者。被叫方的用户代理还将把Contact标头字段放入响应中,其中将包含用户的当前位置。原始请求还包含Contact头字段,这意味着两个用户代理都知道对等方的当前位置。因为用户代理知道彼此的位置,所以没有必要将进一步的请求发送到任何代理-它们可以直接从用户代理发送到用户代理。这正是对话促进路由的方式。对话中的其他消息直接从用户代理发送到用户代理。这是一项显着的性能改进,因为代理不会看到对话中的所有消息,它们仅用于路由建立对话的第一个请求。由于典型的代理通常会实现复杂的路由逻辑,因此直接消息的传递也将具有较小的延迟。图7,“ SIP梯形”包含对话(BYE)中绕过代理的一条消息示例。图7. SIP梯形

1.6.2。对话标识符我们已经显示了对话标识符由三部分组成,即Call-Id,From标签和To标签,但是不清楚为什么对话框标识符正是以这种方式创建的,以及谁贡献了这部分。呼叫ID就是所谓的呼叫标识符。它必须是标识呼叫的唯一字符串。呼叫包含一个或多个对话。当沿路径的代理派生该请求时,多个用户代理可以响应该请求。发送2xx的每个用户代理都会与调用方建立一个单独的对话。所有这些对话都是同一呼叫的一部分,并且具有相同的呼叫ID。发件人标记是由调用方生成的,它在调用方的用户代理中唯一标识对话框。To标签是由被调用方生成的,并且与From标签一样,它唯一标识被调用方的用户代理中的对话。此分层对话标识符是必需的,因为单个呼叫邀请可以创建多个对话,并且呼叫者必须能够区分它们。

典型的SIP方案

本节简要概述通常构成SIP流量的典型SIP方案。

注册(REGISTER)用户必须在注册商处注册才能被其他用户访问。如果注册成功,注册将包含REGISTER消息,然后是注册商发送的200 OK。通常会授权注册,因此如果用户未提供有效的凭据,则会显示407答复。图8“ REGISTER消息流”显示了注册示例。图8. REGISTER消息流

邀请(INVITE)会话邀请包括一个通常发送给代理的INVITE请求。代理立即发送100 Trying回复以停止重传,并进一步转发请求。被呼叫者生成的所有临时响应都将发送回给呼叫者。请参阅呼叫流程中的180振铃响应。当被叫方的电话开始振铃时,将生成响应。图9. INVITE消息流

被呼叫者拿起电话后,将生成200 OK,并由被呼叫者的用户代理重新传输,直到从呼叫者收到ACK。会话在此时建立。

会话终止(BYE)通过在INVITE建立的对话框中发送BYE请求来完成会话终止。BYE消息直接从一个用户代理发送到另一个用户代理,除非INVITE请求路径上的代理指示它希望通过使用记录路由来保留在该路径上(请参见第1.7.4节“记录路由”)。希望拆除会话的一方将BYE请求发送给参与会话的另一方。另一方发送200 OK响应以确认BYE,并且会话终止。请参见图10,“ BYE消息流(有和没有记录路由)”,左消息流。

记录路由(RECORD-ROUTE)默认情况下,对话框中发送的所有请求都直接从一个用户代理发送到另一个用户代理。仅对话框外的请求遍历SIP代理。这种方法使SIP网络具有更高的可伸缩性,因为只有少量的SIP消息可以到达代理服务器。在某些情况下,SIP代理需要停留在所有其他消息的路径上。例如,控制NAT框的代理或进行记帐的代理需要停留在BYE请求的路径上。代理可以通知用户代理它希望保留在所有其他消息路径上的机制称为记录路由。这样的代理会将Record-Route标头字段插入包含代理地址的SIP消息中。然后,在对话框中发送的消息将遍历所有将Record-Route标头字段放入消息中的SIP代理。请求的接收者在消息中收到一组Record-Route标头字段。它必须将所有Record-Route标头字段镜像到响应中,因为请求的发起者还需要知道代理集。图10. BYE消息流(带有和不带有记录路由)

图10的 左侧消息流,“ BYE消息流(带有和不带有记录路由)”显示了当BYE(由INVITE建立的对话框中的请求)在不存在Record-Route标头字段的情况下如何直接发送到另一个用户代理。信息。正确的消息流显示了当代理将Record-Route标头字段放入消息中时情况如何变化。

严格与宽松路由(STRICT AND LOOSE ROUTE)记录路由的工作方式已经发展。根据RFC2543的记录路由重写了Request-URI。这意味着Request-URI始终包含下一跳的URI(可以是插入Record-Route标头字段的下一个代理服务器,也可以是目标用户代理)。因此,有必要将原始Request-URI保存为最后一个Route标头字段。这种方法称为严格路由。RFC3261中指定的松散路由的工作方式略有不同。Request-URI不再被覆盖,它始终包含目标用户代理的URI。如果消息中有任何Route标头字段,则消息将从最顶部的Route标头字段发送到URI。这是一个重大更改-Request-URI不一定包含将请求发送到的URI。实际上,松散路由与IP源路由非常相似。因为从严格路由到松散路由的过渡将破坏向后兼容性,并且较旧的用户代理将不起作用,所以必须使松散路由向后兼容。不幸的是,向后兼容会增加很多开销,并且经常是主要问题的根源。

活动订阅和通知 (EVENT SUBSCRIBE AND NOTIFY)SIP规范已扩展为支持允许订阅异步事件的通用机制。这样的偶数可以包括SIP代理统计信息更改,状态信息,会话更改等。该机制主要用于传达有关用户的存在(通信意愿)的信息。图11“事件订阅和通知”显示了基本消息流。图11.事件订阅和通知

对事件通知感兴趣的用户代理将SUBSCRIBE消息发送到SIP服务器。SUBSCRIBE消息建立一个对话框,并由服务器使用200 OK响应立即答复。至此,对话框建立。每当用户订阅的事件发生更改时,服务器就会向用户发送一个NOTIFY请求。NOTIFY消息在SUBSCRIBE建​​立的对话框中发送。请注意,无论是否有任何触发通知的事件,都会发送图11中的第一条NOTIFY消息“事件订阅和通知”。订阅(以及注册)的寿命有限,因此必须定期刷新。

即时消息 (INSTANT MESSAGE)使用MESSAGE请求发送即时消息。MESSAGE请求不会建立对话框,因此它们将始终遍历同一组代理。这是发送即时消息的最简单形式。即时消息的文本在SIP请求的正文中传输。图12.即时消息