Jingle详解
转载自:http://blog.csdn.net/chenhande1990chenhan/article/details/70174307
1.介绍
Jingle协议的目的是在XMPP实体间建立一对一、点对点的媒体会话,使其在进行媒体数据协商和交互时使用XMPP的信令交互。虽然Jingle协议提供了一个通用的会话管理框架,但是其设计的原始目的仅仅只是为了音视频通讯,强调的是“简单”。Jingle协议的目的不是为了建立一个完整的电话应用程序,包括呼叫等待、呼叫转发、呼叫转移、IVR系统、定位、视频会议等等。这些功能是对jingle感兴趣的用户群体将其添加到了jingle的核心层,专门为了设计简单而广义的会话协议。
此外,Jingle不是为了代替或是取代现有的已经存在了很久的SIP协议,因为双栈式的XMPP+SIP客户端很难创建。Jingle是作为一个纯粹的XMPP信令协议而被设计的。但是,Jingle同时被设计时也能够互通SIP协议使数以百万计的XMPP客户端能够被添加到VoIP网络,而不是限制XMPP用户使其成一个单独的网络。
2.工作流程
事实上,jingle准许两个XMPP实体组件、管理和销毁一个多媒体会话。整个会话协商发生在XMPP上,并且媒体传输发生在XMPP以外,下面介绍一个简单的会话流程:
发Romeo Juliet
| |
| session-initiate |
|---------------------------->|
| ack |
|<----------------------------|
| session-accept |
|<----------------------------|
| ack |
|---------------------------->|
| MEDIA SESSION |
|<===========================>|
| session-terminate |
|<----------------------------|
| ack |
|---------------------------->|
| |
2.1送端发送初始会话(Initiator sends session-initiate (stub))
<iq from='romeo@montague.lit/orchard'
id='zid615d9'
to='juliet@capulet.lit/balcony'
type='set'>
<jingle xmlns='urn:xmpp:jingle:1'
action='session-initiate'
initiator='romeo@montague.lit/orchard'
sid='a73sjjvkla37jfea'>
<content creator='initiator' name='this-is-a-stub'>
<description xmlns='urn:xmpp:jingle:apps:stub:0'/>
<transport xmlns='urn:xmpp:jingle:transports:stub:0'/>
</content>
</jingle>
</iq>
发起者:from='romeo@montague.lit/orchard'
目的:to='juliet@capulet.lit/balcony'
当接收客户端收到发起端发送的会话邀请后,接收端会发送一个消息收到的ack,然后接收端根据自身业务需求进行选择是接收会话还是拒绝会话
2.2接收端发送接收会话
<iq from='juliet@capulet.lit/balcony'
id='rc61n59s'
to='romeo@montague.lit/orchard'
type='set'>
<jingle xmlns='urn:xmpp:jingle:1'
action='session-accept'
responder='juliet@capulet.lit/balcony'
sid='a73sjjvkla37jfea'>
<content creator='initiator' name='this-is-a-stub'>
<description xmlns='urn:xmpp:jingle:apps:stub:0'/>
<transport xmlns='urn:xmpp:jingle:transports:stub:0'/>
</content>
</jingle>
</iq>
发送端收到接收端的接收会话消息后会给ack发送一个确认收到的ack消息,然后双方将会交换“stub”媒体数据信息。
事实上,双发都可以终止会话,下面是接收端发送的终止会话信息:
2.3接收端终止会话
<iq from='juliet@capulet.lit/balcony'
id='le71fa63'
to='romeo@montague.lit/orchard'
type='set'>
<jingle xmlns='urn:xmpp:jingle:1'
action='session-terminate'
sid='a73sjjvkla37jfea'>
<reason>
<success/>
</reason>
</jingle>
</iq>
发送端接收到终止会话后给接收端发送一个确认收到的ack消息,整个会话结束。
下面我们将给出整个消息完整的Jingle格式,主要添加<description/> 和<transport/>元素,以下例子会包含语音聊天会话(Jingle RTP)会话和传输方式(ICE-UDP).
2.4发送端发送详细的初始会话stub
A<iq from='romeo@montague.lit/orchard'
id='ph37a419'
to='juliet@capulet.lit/balcony'
type='set'>
<jingle xmlns='urn:xmpp:jingle:1'
action='session-initiate'
initiator='romeo@montague.lit/orchard'
sid='a73sjjvkla37jfea'>
<content creator='initiator' name='voice'>
<description xmlns='urn:xmpp:jingle:apps:rtp:1' media='audio'>
<payload-type id='96' name='speex' clockrate='16000'/>
<payload-type id='97' name='speex' clockrate='8000'/>
<payload-type id='18' name='G729'/>
<payload-type id='0' name='PCMU' />
<payload-type id='103' name='L16' clockrate='16000' channels='2'/>
<payload-type id='98' name='x-ISAC' clockrate='8000'/>
</description>
<transport xmlns='urn:xmpp:jingle:transports:ice-udp:1'
pwd='asd88fgpdd777uzjYhagZg'
ufrag='8hhy'>
<candidate component='1'
foundation='1'
generation='0'
id='el0747fg11'
ip='10.0.1.1'
network='1'
port='8998'
priority='2130706431'
protocol='udp'
type='host'/>
<candidate component='1'
foundation='2'
generation='0'
id='y3s2b30v3r'
ip='192.0.2.3'
network='1'
port='45664'
priority='1694498815'
protocol='udp'
rel-addr='10.0.1.1'
rel-port='8998'
type='srflx'/>
</transport>
</content>
</jingle>
</iq>
当接收端接收到会话后,将会决定是否继续进行会话,如果没有错误,就会发送ack确认收到。
2.5 接收端发送ack确认消息
<iq from='juliet@capulet.lit/balcony'
id='ph37a419'
to='romeo@montague.lit/orchard'
type='result'/>
当接收端发送确认ack后就会继续进行会话,然后接收客户端将会发送给客户端一个接收会话的消息(这个消息包含接收端的编解码的支持和多个备选传输方式)。
2.6接收端发送详细的接收会话
<iq from='juliet@capulet.lit/balcony'
id='yd71f495'
to='romeo@montague.lit/orchard'
type='set'>
<jingle xmlns='urn:xmpp:jingle:1'
action='session-accept'
responder='juliet@capulet.lit/balcony'
sid='a73sjjvkla37jfea'>
<content creator='initiator' name='voice'>
<description xmlns='urn:xmpp:jingle:apps:rtp:1' media='audio'>
<payload-type id='97' name='speex' clockrate='8000'/>
<payload-type id='18' name='G729'/>
</description>
<transport xmlns='urn:xmpp:jingle:transports:ice-udp:1'>
<candidate component='1'
foundation='1'
generation='0'
id='or2ii2syr1'
ip='192.0.2.1'
network='0'
port='3478'
priority='2130706431'
protocol='udp'
type='host'/>
</transport>
</content>
</jingle>
</iq>
接下来发送端将会发送ack确认信息。
2.7发送端发送ack确认消息
<iq from='romeo@montague.lit/orchard'
id='yd71f495'
to='juliet@capulet.lit/balcony'
type='result'/>
当双方结束会话协商后,就会进行双方可以接受的媒体数据传输。
2.8接收端发送详细的终止会话
<iq from='juliet@capulet.lit/balcony'
id='vua614d9'
to='romeo@montague.lit/orchard'
type='set'>
<jingle xmlns='urn:xmpp:jingle:1'
action='session-terminate'
sid='a73sjjvkla37jfea'>
<reason>
<success/>
<text>Sorry, gotta go!</text>
</reason>
</jingle>
</iq>
发送端发送ack确认消息
2.9 接收端发送ack确认消息
<iq from='romeo@montague.lit/orchard'
id='vua614d9'
to='juliet@capulet.lit/balcony'
type='result'/>
3.需求
Jingle协议满足如下需求:
1、支持基于XMPP的广泛的P2P会话,不仅限于音视频;
2、当P2P连接没有正常协商,能够回滚到上一层;
3、从数据交互通道上清晰的分离了信号通道(XMPP);
4、从传输方式上(比如UDP)清晰的分离了应用方式(比如RTP);
5、在已存在的会话上能够添加、修改双方应用方式和传输方式;
6、使双方都能相对容易在Jabber/XMPP客户端对协议的支持;
7、对双方是非XMPP协议的,可以基于网关使XMPP协议和非XMPP协议能够相互转化。
4.术语
4.1术语
应用方式:双方会话过程中(比如音视频会话)能够成功建立和支持的数据格式,比如编可支持的解码格式,在Jingle协议中用<description/>元素表示。
组成:序列化的流两个终端进行传输时需要一个数据格式方便双方进行控制流的传输和对流的编解码,因此有些组成元素是必须要的。(比如RTP和RTCP)
支持类型:包括双方的应用方式和传输方式。
会话:双方开始信息发送到整个信息交互结束,这整个过程就叫做一个会话
传输方式:指的是流数据进行交互时的方式,包括ICE-UDP, ICE-TCP, Raw UDP, In-Band Bytestreams, SOCKS5 Bytestreams等等,在jingle协议中用<transport/>元素表示,传输方式定义了如何将数据字节从一个终端传送给另一个终端,传输方式必须定义清楚是数据包还是流数据。
4.2定义
在上述图解表示中,有以下两种方式:
1、单虚线 (---),代表jingle方式的xmpp协议;
2、双虚线 (===),代表媒体包传输时的数据通道。
5.概念和方式
Jingle协议包含三个组成部分:
1、全方位的session管理;
2、应用方式(what);
3、传输方式(how)
一个最基本的jingle会话协商包括以下几点:
1、session-initiate消息必须包含最少一个内容,每个内容必须定义一个应用方式、传输方式和任意的安全前提;
2、如果接收端希望继续会话,需要发送一个session-accept消息给发送端,这个消息必须包含一个和多个传输候选项;
3、双方建立连接时需要提供传输方式,包括交换信息和传输候选,如果没法正常建立连接,双方则可回退到其他传输方式,可以使用 transport-replace和transport-accept消息;
4、在传输应用数据前双方需要建立安全的传输方式;
5、任何一方需要改变媒体的流向,可以使用 content-add, content-remove,和content-modify消息;
6、双方可以发送session-info消息(比如对方的响铃信息);
7、一旦双方确定了数据在协商传输上的流向,要开始发送应用数据。
5.1全方位的会话管理
o
|
| session-initiate
|
| +---------->--------------+
|/ |
PENDING o-----------------------+ |
| | content-accept, | |
| | content-add, | |
| | content-modify, | |
| | content-reject, | |
| | content-remove, | |
| | description-info, | |
\|/ | session-info, | |
| | transport-accept, | |
| | transport-info, | |
| | transport-reject, | |
| | transport-replace | |
| +-------------------+ |
| |
| session-accept \|/
| |
ACTIVE o-----------------------+ |
| | content-accept, | |
| | content-add, | |
| | content-modify, | |
| | content-reject, | |
| | content-remove, | |
| | description-info, | |
\|/ | session-info, | |
| | transport-accept, | |
| | transport-info, | |
| | transport-reject, | |
| | transport-replace | |
| +-------------------+ |
| |
+------------>--------------+
|
| session-terminate
|
o ENDED
通过上述图表,可以看到三种会话状态:
1、PENDING
2、ACTIVE
3、ENDED
content-accept
Accept a content-add action received from another party.
content-add
Add one or more new content definitions to the session.
content-modify
Change the directionality of media sending.
content-reject
Reject a content-add action received from another party.
content-remove
Remove one or more content definitions from the session.
description-info
交换应用方式参数信息
session-accept
接受一个会话
session-info
会话信息,比如ping和响铃信息
session-initiate
会话邀请
session-terminate
会话结束
transport-accept
接受传输替换方式
transport-info
交换传输候选
transport-reject
拒绝传输替换
transport-replace
重新顶底传输方式或者替换一个不同的传输方式
6.会话流向
6.1资源决定
为了初始化一个jingle会话,发送端需要确认接收端的哪一个XMPP资源是最好的应用方式。
6.2 发送端发送
一旦发送端确定了接收端需要的最理想的应用格式的XMPP资源,将会发送一个会话邀请给接收端,这是一个IQ-set消息包含jingle元素,'urn:xmpp:jingle:1' namespace (see Namespace Versioning),action='session-initiate',一个和多个<content/>元素,每个<content/>元素必须包含<description/> (应用方式)和 <transport/>(传输方式),<security/>(数据交互和协商之前的安全规则)
6.2.1 Initiator sends session-initiate
<iq from='romeo@montague.lit/orchard'
id='xs51r0k4'
to='juliet@capulet.lit/balcony'
type='set'>
<jingle xmlns='urn:xmpp:jingle:1'
action='session-initiate'
initiator='romeo@montague.lit/orchard'
sid='a73sjjvkla37jfea'>
<content creator='initiator' name='voice'>
<description xmlns='urn:xmpp:jingle:apps:rtp:1' media='audio'>
<payload-type id='96' name='speex' clockrate='16000'/>
<payload-type id='97' name='speex' clockrate='8000'/>
<payload-type id='18' name='G729'/>
<payload-type id='0' name='PCMU' />
<payload-type id='103' name='L16' clockrate='16000' channels='2'/>
<payload-type id='98' name='x-ISAC' clockrate='8000'/>
</description>
<transport xmlns='urn:xmpp:jingle:transports:ice-udp:1'
pwd='asd88fgpdd777uzjYhagZg'
ufrag='8hhy'>
<candidate component='1'
foundation='1'
generation='0'
id='el0747fg11'
ip='10.0.1.1'
network='1'
port='8998'
priority='2130706431'
protocol='udp'
type='host'/>
<candidate component='1'
foundation='2'
generation='0'
id='y3s2b30v3r'
ip='192.0.2.3'
network='1'
port='45664'
priority='1694498815'
protocol='udp'
rel-addr='10.0.1.1'
rel-port='8998'
type='srflx'/>
</transport>
</content>
</jingle>
</iq>
6.3 接收端接收
6.3.1 Ack
对于任何一个收到的会话消息都要发送ACK进行消息确认收到。
<iq from='juliet@capulet.lit/balcony'
id='xs51r0k4'
to='romeo@montague.lit/orchard'
type='result'/>
6.3.2 Errors
以下几种情况将会发送一个error信息来替代ack的确认信息
1、接收端不认识发送端
<iq from='juliet@capulet.lit/balcony'
id='xs51r0k4'
to='romeo@montague.lit/orchard'
type='error'>
<error type='cancel'>
<service-unavailable xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
</error>
</iq>
2、接收端不支持jingle
<iq from='juliet@capulet.lit/balcony'
id='xs51r0k4'
to='romeo@montague.lit/orchard'
type='error'>
<error type='cancel'>
<service-unavailable xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
</error>
</iq>
3、接收端需要重定向地址
<iq from='juliet@capulet.lit/balcony'
id='xs51r0k4'
to='romeo@montague.lit/orchard'
type='error'>
<error type='modify'>
<redirect xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'>
xmpp:voicemail@capulet.lit
</redirect>
</error>
</iq>
4、接收端无法满足资源需求来建立一个会话
<iq from='juliet@capulet.lit/balcony'
id='xs51r0k4'
to='romeo@montague.lit/orchard'
type='error'>
<error type='wait'>
<resource-constraint xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
</error>
</iq>
5、发送端的请求是畸形的
<iq from='juliet@capulet.lit/balcony'
id='xs51r0k4'
to='romeo@montague.lit/orchard'
type='error'>
<error type='cancel'>
<bad-request xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
</error>
</iq>
6.4 协商
一般而言,虽然对于接收者而言越快发送session-accept越好,但是很多协商是必要的在连接建立之前,比如应用方式和通讯方式。以下内容是需要通过协商来确定的:
1、通过transport-info交换传输候选;
2、通过content-modify修改通讯指向;
3、通过transport-replace改变内容方式;
4、通过content-add添加内容方式;
5、通过content-remove移除内容方式。
6.5 接受
6.5.1 Responder accepts the session
<iq from='juliet@capulet.lit/balcony'
id='jd82f517'
to='romeo@montague.lit/orchard'
type='set'>
<jingle xmlns='urn:xmpp:jingle:1'
action='session-accept'
responder='juliet@capulet.lit/balcony'
sid='a73sjjvkla37jfea'>
<content creator='initiator' name='voice'>
<description xmlns='urn:xmpp:jingle:apps:rtp:1' media='audio'>
<payload-type id='97' name='speex' clockrate='8000'/>
<payload-type id='18' name='G729'/>
</description>
<transport xmlns='urn:xmpp:jingle:transports:ice-udp:1'>
<candidate component='1'
foundation='1'
generation='0'
id='or2ii2syr1'
ip='192.0.2.1'
network='0'
port='3478'
priority='2130706431'
protocol='udp'
type='host'/>
</transport>
</content>
</jingle>
</iq>
6.5.2 Initiator acknowledges session acceptance
<iq from='romeo@montague.lit/orchard'
id='jd82f517'
to='juliet@capulet.lit/balcony'
type='result'/>
6.6修改会话
一旦会话属于活跃状态,可以通过content-add, content-modify, content-remove, or transport-info消息来修改
6.7结束会话
一旦双方结束会话,则需要发送session-terminate消息来结束会话,会话结束必须包含<reason/>消息。
6.6.1 成功结束Terminating the session (success)
<iq from='juliet@capulet.lit/balcony'
id='bv81gs75'
to='romeo@montague.lit/orchard'
type='set'>
<jingle xmlns='urn:xmpp:jingle:1'
action='session-terminate'
sid='a73sjjvkla37jfea'>
<reason>
<success/>
</reason>
</jingle>
</iq>
6.6.2 忙线结束Terminating the session (busy)
<iq from='juliet@capulet.lit/balcony'
id='hr81fs63'
to='romeo@montague.lit/orchard'
type='set'>
<jingle xmlns='urn:xmpp:jingle:1'
action='session-terminate'
sid='a73sjjvkla37jfea'>
<reason>
<busy/>
</reason>
</jingle>
</iq>
6.6.3 减少会话结束Terminating the session (session formally declined)
<iq from='juliet@capulet.lit/balcony'
id='ky47g295'
to='romeo@montague.lit/orchard'
type='set'>
<jingle xmlns='urn:xmpp:jingle:1'
action='session-terminate'
sid='a73sjjvkla37jfea'>
<reason>
<decline/>
</reason>
</jingle>
</iq>
6.6.4 会话存在结束Terminating the session (existing session)
<iq from='juliet@capulet.lit/balcony'
id='ay3r2b86'
to='romeo@montague.lit/orchard'
type='set'>
<jingle xmlns='urn:xmpp:jingle:1'
action='session-terminate'
sid='a73sjjvkla37jfea'>
<reason>
<alternative-session>
<sid>b84tkkwlmb48kgfb</sid>
</alternative-session>
</reason>
</jingle>
</iq>
6.6.5 会话传输方式不存在结束Terminating the session (no offered transport method supported)
<iq from='juliet@capulet.lit/balcony'
id='h82bs51g'
to='romeo@montague.lit/orchard'
type='set'>
<jingle xmlns='urn:xmpp:jingle:1'
action='session-terminate'
sid='a73sjjvkla37jfea'>
<reason>
<unsupported-transports/>
</reason>
</jingle>
</iq>
6.6.6 会话协商失败结束Terminating the session (transport negotiation failed)
<iq from='juliet@capulet.lit/balcony'
id='pe81ga88'
to='romeo@montague.lit/orchard'
type='set'>
<jingle xmlns='urn:xmpp:jingle:1'
action='session-terminate'
sid='a73sjjvkla37jfea'>
<reason>
<failed-transport/>
</reason>
</jingle>
</iq>
6.6.7 会话应用方式不存在结束Terminating the session (no offered application type supported)
<iq from='juliet@capulet.lit/balcony'
id='yd62vd67'
to='romeo@montague.lit/orchard'
type='set'>
<jingle xmlns='urn:xmpp:jingle:1'
action='session-terminate'
sid='a73sjjvkla37jfea'>
<reason>
<unsupported-applications/>
</reason>
</jingle>
</iq>
6.6.8 会话应用建立失败结束Terminating the session (application setup failed)
<iq from='juliet@capulet.lit/balcony'
id='kd82vs71'
to='romeo@montague.lit/orchard'
type='set'>
<jingle xmlns='urn:xmpp:jingle:1'
action='session-terminate'
sid='a73sjjvkla37jfea'>
<reason>
<failed-application/>
</reason>
</jingle>
</iq>
6.6.9 会话Ack正常结束 Acknowledging termination
<iq from='romeo@montague.lit/orchard'
id='h82bs51g'
to='juliet@capulet.lit/balcony'
type='result'/>
6.6.10 会话未知错误结束Unknown-session error
<iq from='romeo@montague.lit/orchard'
id='ur71vs62'
to='juliet@capulet.lit/balcony'
type='error'>
<error type='cancel'>
<item-not-found xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
<unknown-session xmlns='urn:xmpp:jingle:errors:1'/>
</error>
</iq>
6.7 情报消息
6.7.1 接收者发送响铃消息
<iq from='juliet@capulet.lit/balcony'
id='hq7rg186'
to='romeo@montague.lit/orchard'
type='set'>
<jingle xmlns='urn:xmpp:jingle:1'
action='session-info'
sid='a73sjjvkla37jfea'>
<ringing xmlns='urn:xmpp:jingle:apps:rtp:1:info'/>
</jingle>
</iq>
6.7.2 接收者返回unsupported-info错误消息
<iq from='romeo@montague.lit/orchard'
id='hq7rg186'
to='juliet@capulet.lit/balcony'
type='error'>
<error type='modify'>
<feature-not-implemented xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
<unsupported-info xmlns='urn:xmpp:jingle:errors:1'/>
</error>
</iq>
6.7.3 接收者发送session ping消息
<iq from='juliet@capulet.lit/balcony'
id='ug37vb25'
to='romeo@montague.lit/orchard'
type='set'>
<jingle xmlns='urn:xmpp:jingle:1'
action='session-info'
sid='a73sjjvkla37jfea'/>
</iq>
6.7.4 发送者返回IQ-result消息
<iq from='romeo@montague.lit/orchard'
id='ug37vb25'
to='juliet@capulet.lit/balcony'
type='result'/>
7.形式定义
7.1 Jingle元素
<jingle/n>可以是空的,也可以包含一个或者多个<content/>元素,jingle的属性元素如下:
定义 | 包含 | |
action | 行为属性章节会详细介绍 | REQUIRED |
initiator* | 发送端采用的initiator=”JID”(发送端的JID) | RECOMMENDED for session-initiate, NOT RECOMMENDED otherwise |
responder* | 接收端采用的 responder=”JID”(接收端的JID) | RECOMMENDED for session-accept, NOT RECOMMENDED otherwise |
sid | 会话开始时产生的唯一标识ID,整个会话都用此ID | REQUIRED |
7.2 行为属性
行为属性的值必须是以下中的一个,如果一个实体接收到了未定义的行为属性,必须返回一个<bad-request/>错误给发送者。
7.2.1 content-accept
The content-accept action is used to accept a content-add action received from another party.
7.2.2 content-add
The content-add action is used to add one or more new content definitions to the session. The sender MUST specify only the added content definition(s), not the added content definition(s) plus the existing content definition(s). Therefore it is the responsibility of the recipient to maintain a local copy of the current content definition(s). If the recipient wishes to include the new content definition in the session, it MUST send a content-accept action to the other party; if not, it MUST send a content-reject action to the other party.
7.2.3 content-modify
The content-modify action is used to change the direction of an existing content definition through modification of the 'senders' attribute. If the recipient deems the directionality of a content-modify action to be unacceptable, it MAY reply with a contrary content-modify action, terminate the session, or simply refuse to send or accept application data in the new direction. In any case, the recipient MUST NOT send a content-accept action in response to the content-modify.
7.2.4 content-reject
The content-reject action is used to reject a content-add action received from another party.
If the content-reject results in zero content definitions for the session, the entity that receives the content-reject SHOULD send a session-terminate action to the other party (since a session with no content definitions is void).
7.2.5 content-remove
The content-remove action is used to remove one or more content definitions from the session. The sender MUST specify only the removed content definition(s), not the removed content definition(s) plus the remaining content definition(s). Therefore it is the responsibility of the recipient to maintain a local copy of the current content definition(s). Upon receiving a content-remove from the other party, the recipient MUST NOT send a content-accept and MUST NOT continue to negotiate the transport method or send application data related to that content definition.
If the content-remove results in zero content definitions for the session, the entity that receives the content-remove SHOULD send a session-terminate action to the other party (since a session with no content definitions is void).
7.2.6 description-info
交换应用方式参数信息,比如视频播放区域挥着音频流的配置
7.2.7 security-info
The security-info action is used to send information related to establishment or maintenance of security preconditions.
7.2.8 session-accept
接收会话
7.2.9 session-info
会话信息,比如ping和响铃信息
7.2.10 session-initiate
会话邀请
7.2.11 session-terminate
会话结束
7.2.12 transport-accept
The transport-accept action is used to accept a transport-replace action received from another party.
7.2.13 transport-info
The transport-info action is used to exchange transport candidates; it is mainly used in Jingle ICE-UDP but might be used in other transport specifications.
7.2.14 transport-reject
The transport-reject action is used to reject a transport-replace action received from another party.
7.2.15 transport-replace
The transport-replace action is used to redefine a transport method, typically for fallback to a different method (e.g., changing from ICE-UDP to Raw UDP for a datagram transport, or changing from SOCKS5 Bytestreams (XEP-0065) [8] to In-Band Bytestreams (XEP-0047) [10] for a streaming transport). If the recipient wishes to use the new transport definition, it MUST send a transport-accept action to the other party; if not, it MUST send a transport-reject action to the other party.
7.2.16 Tie Breaking Related to Jingle Actions
It is possible that the same Jingle action can be sent at the same time by both parties. There are two possible scenarios:
No existing session
If there is no existing session and both parties simultaneously send a Jingle session-initiate message with a content-type that is functionally equivalent (e.g., each message requests initiation of a voice call), the action with the lower of the two session IDs MUST overrule the other action, where by "lower" is meant the session ID that is sorted first using "i;octet" collation as specified in Section 9.3 of RFC 4790 [26] (in the unlikely event that the random session IDs are the same, the action sent by the lower of the JabberIDs MUST overrule the other action). The party that receives the session-initiate action with the lower of the two session IDs MUST acknowledge the action or return an error condition that would normally be returned when receiving a session-initiate message, and the party that receives the session-initiate action with the higher of the two session IDs MUST return a <conflict/> error to the other party, which SHOULD include a Jingle-specific condition of <tie-break/>.
Existing session
In the context of an existing session, the action sent by the initiator MUST overrule the action sent by the responder; i.e., both parties MUST accept the action sent by the initiator and the initiator MUST return a <conflict/> error to the responder for the duplicate action, which SHOULD include a Jingle-specific condition of <tie-break/>.
In both scenarios, the error to be returned is <conflict/>, as shown in the following example.
Example 34. Initiator returns conflict error on tie-break
<iq from='romeo@montague.lit/orchard'
id='hb2f164w'
to='juliet@capulet.lit/balcony'
type='error'>
<error type='cancel'>
<conflict xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
<tie-break xmlns='urn:xmpp:jingle:errors:1'/>
</error>
</iq>
7.3 Content Element
Attribute | Definition | Inclusion |
creator | 对应的值一般是"initiator"和"responder",默认是"initiator" | REQUIRED |
disposition | How the content definition is to be interpreted by the recipient. The meaning of this attribute matches the "Content-Disposition" header as defined in RFC 2183 [27] and applied to SIP by RFC 3261. The value of this attribute SHOULD be one of the values registered in the IANA Mail Content Disposition Values and Parameters Registry [28]. The default value of this attribute is "session". | OPTIONAL |
name | A unique name or identifier for the content type according to the creator, which MAY have meaning to a human user in order to differentiate this content type from other content types (e.g., two content types containing video media could differentiate between "room-pan" and "slides"). If there are two content types with the same value for the 'name' attribute, they shall understood as alternative definitions for the same purpose (e.g., a legacy method and a standards-based method for establishing a voice call), typically to smooth the transition from an older technology to Jingle. | REQUIRED |
senders | 对应的值一般是 "both", "initiator", "none", 和 "responder" ,默认是 "both"). 对应 SDP属性的"sendrecv", "sendonly", "inactive", and "recvonly" | OPTIONAL except when sending content-modify, in which case it is REQUIRED. |
7.4 Reason Element
元素 | 描述 |
<alternative-session/> | 通过SID号重新连接一个新的会话 |
<busy/> | 忙线 |
<cancel/> | 取消会话 |
<connectivity-error/> | 连接错误 |
<decline/> | 减少会话 |
<expired/> | The session length has exceeded a pre-defined time limit (e.g., a meeting hosted at a conference service). |
<failed-application/> | 初始化应用方式错误 |
<failed-transport/> | 连接方式建立错误 |
<general-error/> | 未定义应用错误 |
<gone/> | 离线 |
<incompatible-parameters/> | 参数错误 |
<media-error/> | 媒体错误 |
<security-error/> | 安全错误 |
<success/> | 成功结束 |
<timeout/> | 超时 |
<unsupported-applications/> | 不支持的应用方式 |
<unsupported-transports/> | 不支持的传输方式 |
8.传输方式
8.1 数据包
数据包的传输往往是一个或者多个UDP数据包组成。
8.2 流
流传输需要包含一个或者多个组成来保证TCP的可靠传输。
9.安全前提
9.1 Initiator sends session-initiate with security precondition (stub)
<iq from='romeo@montague.lit/orchard'
id='tiw51bv9'
to='juliet@capulet.lit/balcony'
type='set'>
<jingle xmlns='urn:xmpp:jingle:1'
action='session-initiate'
initiator='romeo@montague.lit/orchard'
sid='a73sjjvkla37jfea'>
<content creator='initiator' name='this-is-a-stub'>
<description xmlns='urn:xmpp:jingle:apps:stub:0'/>
<transport xmlns='urn:xmpp:jingle:transports:stub:0'/>
<security xmlns='urn:xmpp:jingle:security:stub:0'/>
</content>
</jingle>
</iq>
9.2 Initiator sends security-info message
<iq from='romeo@montague.lit/orchard'
id='zyw6m167'
to='juliet@capulet.lit/balcony'
type='set'>
<jingle xmlns='urn:xmpp:jingle:1'
action='security-info'
sid='a73sjjvkla37jfea'>
<content creator='initiator' name='xmlstream'>
<security xmlns='urn:xmpp:jingle:security:xtls:0'>
<method name='x509'/>
</security>
</content>
</jingle>
</iq>
9.3 Initiator sends security-required error
<iq from='romeo@montague.lit/orchard'
id='bsi381f5'
to='juliet@capulet.lit/balcony'
type='error'>
<error type='cancel'>
<not-acceptable xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
<security-required xmlns='urn:xmpp:jingle:errors:1'/>
</error>
</iq>