当我们讨论SIP或者SDP的一些技术话题时,SDP的协商是一个绕不过的话题。具体的协商机制涉及了多个方面的内容。在我们的讨论中,笔者将会针对两个比较重要的话题进行讨论,一个是SDP offer/answer 模式,另外一个是在NAT场景中的SDP offer/answer交互模式拓展ICE。在本章节中,我们将首先讨论SDP offer/answer交互模式,具体内容包括:offer/answer的背景介绍,基本操作,如何实现初始化的offer,重点讨论offer中的单播媒体操作,offer中关于指示方向的处理策略,编码协商优先级设置。
背景介绍和基本操作
首先,我们介绍一下我们讨论的基本背景环境。到目前为止,我们讨论的核心话题涉及了SDP和准备要讨论的offer/anser交互模式。基本上我们都是围绕两个核心的规范来讨论,其中,RFC4566(SDP)为基本蓝图,然后配合RFC3264关于offer/answer交互模式。关于SDP的内容,我们在前面的章节已经有完整的介绍(SDP基础),那个章节涵盖了SDP的核心定义/专有名词,语法,特征属性,使用场景等相关细节,读者可以查阅上一个章节的内容,这里不再赘述。根据上一个章节的内容,我们在本章节进一步讨论SDP协商时使用的交互模式offer/answer模式。在本章节,我们将重点以RFC3264为蓝本,介绍offer/anwer交互模式。
笔者主要以offer和answer两个部分为核心主线,分别按照两个部分中的单播媒体和多播媒体的处理方式的不同来展开讨论。这里提醒读者,为了更好地支持IPv4,在RFC3264的基础上,RFC6157对媒体描述管理进行了更新。因此,如果读者涉及了在IPv6环境中关于SDP中的媒体描述,读者可以查阅RFC 6157-4.1章节的细节。如果读者对SDP协商模式有兴趣的
话,可以结合具体的代码示例来做进一步的研究。
关于生成初始化offer处理流程
我们讨论生成offer消息之前,首先我们一定要确定,无论是offer消息还是answer消息,它们一定是一个有效的SDP消息。在SDP中针对offer/answer的构成语法可以忽略“e”或者“p=”行。笔者不清楚为什么在
offer/answer的消息中可以忽略“e”或者“p=”行,难道因为这两个会话描述不是十分重要的协商参数? “o“行中的会话ID的数值和版本号必须是一个64位的有符号整形数,并且版本的初始值必须小于(2\\62) − 1,这样可以防止翻转。在SDP规范中,可以允许多个SDP会话描述拼接在一起构成一个大的SDP消息,**但是SDP消息使用在offer/answer交互模式下
时,一个SDP消息必须包含一个完整的会话描述**。
读者知道,SDP中的's='传递会话主题,这种定义方式对多播会话方式是非常合理的,但是对单播会话方式存在一定问题。因此,一般推荐是”s“行有一个单空格字符或一个破折号构成。SDP 't='行负责传递会话时间,通常情况下,对单播会话的媒体来说,它的创建或者结束一般来自于外部的信令的控制,例如,我们现在讨论的SIP协议。那种情况下,'t='行应该设定为”0 0.“。offer消息中包含零个或者多个媒体流,每个媒体流通过”m=“行的媒体会话和其关联特征属性进行说明。读者可能不明白,为什么offer消息中可能会包含零媒体信息?其实,包含零媒体仍然有它的原因。如果offer消息中包含零个媒体,这表示发起方-offerer希望和对端通信,但是发起方会在将来某一时间时间在此会话中添加那个媒体,添加媒体的方式是通过发送一个修改的offer来处理。 此媒体可以是一个单播和多播的混合。如果是多播的媒体,那offer消息中需要在'c='行添加多播地址。它们的构成方式取决于它们的媒体是单播还是多播媒体。简单
理解,这里的零媒体不是表示offer没有什么可做,这表示发起方可能将来在某一时间发起媒
关于offer的单播媒体处理讨论
这里,我们花费一点时间需要详细说明offer中的单播媒体处理流程。在offer中的单播媒体处理中,offer对媒体的发送和接收标注涉及了多个方向指示特征属性(a=sendonly,a=recvonly,a=sendrecv,a=inactive-参考RFC3108和RFC2327),多个特征属性又具有不同的含义,所以请读者在阅读本部分内容时一定要特别注意。读者也可以查阅笔者的历史文档来学习关于这三种属性应用场景示例。
如果offer仅希望对对端发送媒体时,offer必须对此媒体标注为send-only的表示,通过特征属性'a=sendonly'行来标识。如果媒体发送的方向属性作为媒体媒体流属性或者会话属性出现的话,我们就会认为此媒体标注了媒体发送方向。同理,如果此offer仅希望从对端接收媒体的话,offer必须对此媒体标识为recvonly,表示仅为接收状态,通过特征属性
“a=recvonly”表示。如果,offer希望和对端通信,但是,此时,offer既不想发送媒体也不行接收媒体时,它通过对媒体标识为'a=inactive'行来表示其当时状态。
这里,笔者需要提醒一下,因为很多最新的规范已经对RTP协议的实时应用程序传输协议RFC3550进行了更新(包括5761,6051,6222,7022,7160,7164,8083和8108),因此一些特别的处理流程需要提醒读者。如果是涉及了RFC3550中描述的实时传输协议和实时传输控制需要的话,为了支持以上三种方向指示的状态,RTCP同样需要被发送和接收。这种
情况下,媒体流的方向指示不会影响RTCP的使用。如果offer希望对对端发送和接收媒体的话,它可以通过'a=sendrecv'行来标识也可以忽略其属性设置(因为此属性为默认设置属性)。
读者需要注意,offer消息中三种媒体流向的方向有一些不同。对于标记了“a=recvonly”和“a=sendrecv”的媒体流来说,在offer消息中,端口号和地址表示发起方offerer希望接收媒体流的端口和地址。对于标识为“a=sendonly” RTP 媒体流,端口号和地址间接指示为offerer希望接收RTCP数据的地址。除非有明确表示说明,否则RTCP报表数据将会发送到
比标识的端口高一位的端口(这是默认的RTCP端口发送方式)。
很多时候,读者可能对offer中的IP地址和端口使用有一些误解,这里笔者做进一步的解释。在offer中出现的ip地址和端口不能指示将要由发起方offerer发送出去的RTP/RTCP的源地址,源端口。在offer消息中,
如果端口数为零,这表示媒体已经被经过offer消息处理,但是此媒体一定不能被使用,因为此初始的offer中没有任何有效的语法参数。有时,如果设置端口零可以结束现存的媒体流。一般来说,端口数量为零表示此媒体流不是offer/answer双方需要的媒体流。但是,一些特殊的环境下,编码类型一样,但是可能因为payload不同的话,也可能需要做一些协商处理。
针对标识为”a=sendonly“ 或“a=sendrecv”的媒体,在answer的消息中同样的媒体可能标识了不同的payload。offerer发起方收到answerer回复后,重新发送一个offer。这次发送中,offerer发起方必须包含一个和answer消息中一样的媒体payload。这样才能保证双方的媒体的payload一致性。有时,为了保证和H323的兼容性,每个方向可以支持不同的
payload类型号。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。