SyncML 同步协议(SyncML Sync Protocol)
翻译周鹏
2006-1-24
摘要
本规范定义了SyncML客户和服务的同步协议。
它规范了怎样使用SynML表示层协议去完成SyncML客户端和服务端的操作。
1. 介绍
本规范的目的是用SyncML表示层协议(using the SyncML Representation protocol)定义同步协议.本协议的名称称为SyncML 同步协议,为不同的同步过程定义协议,同步过程发生在SyncML客户端和服务端.它们间的消息顺序图参考MSC's. 本规范包含了一些普通的有用的同步案例.
1.1 SyncML框架
通过SyncML框架(图一)提供的SyncML接口实现本规范.本规范不要求实现SyncML接口的所有特征.
图一 SyncML框架
应用"A" 描述的是一个提供网络同步服务的应用程序. 应用"B"是相同网络上面的设备.服务和设备使用相同的网络传输协议(HTTP).
在上图中,同步引擎在SyncML服务器中实现,有时也可以在客户端提供同步引擎.SyncML 接口
同步服务代理(Sync server)和客户同步代理(Client Agent)使用本协议和SyncML 接口(the SyncML interface
'SyncML I/F')提供表示层协议.
1.2 设备的角色
图二描述了一部作为SyncML客户的手机和一个SyncML 服务器同步的例子. SyncML 客户发送 SyncML消息给SyncML服务器, 这个SyncML消息包含了SyncML 客户的修改数据.服务器同步数据(包含可能的增加 修改 删去),数据是服务器的同步消息(SyncML messages),之后,同步服务器(the SyncML server)返回给同步客户(SynML Client)它的修改数据.
图二 移动电话和服务器同步的例子
上图提供了一个十分简单的例子,描述了规范中的设备角色:
同步客户端(SyncML Client)- 设备包含了同步客户代理,它首先发送它的修改数据给服务器. 客户必须能够接收同步服务器(the SyncML server)的影响. 同步客户端(SyncML Client)通常首先发送修改,但是,有些情况下服务器会首先初始化同步.同步客户端通常是移动电话设备,个人电脑,PDA 设备.
同步服务器(SyncML server)-- 它是包含了同步引擎和同步代理的设备.通常是等待通步客户端发发起
同步请求和修改数据.当它收到客户的修改数据,服务器处理同步分析并且给客户端响应.
同步服务器在传输协议层可以主动的发送命令初始化同步. 典型的同步服务器设备是服务设备或者是个人电脑
1.3 同步类型
本规范定了七种同步类型,将在下面表一种介绍
表一 SyncML同步类型
同步类型 | 描述 | 参考 |
两方同步类型 (Two-way sync) | 普通的同步类型,客户端和服务器相互交换修改数据,客户端首先发送修改. | 第五章 |
慢同步 (Slow sync) | 一种双方同步的形式,服务器需要比较客户端的每一项数据的每一个字段,这种同步方式客户端需要把全部数据发送给服务器.然后服务器进行比较. | 第五章五节 |
客户端方同步(One-way sync from client only) | 客户端发送它的修改数据给服务器,服务器步发送修改给客户端 | 第六章 |
客户端更新同步 (Refresh sync from client only) | 客户端发送所有的数据给服务器,替换服务器中的数据 | 第六章第三节 |
服务器端单方同步(One-way sync from server only) | 客户端获得所有的服务器的修改数据,客户端不发送自己的修改数据给服务器 | 第七章 |
服务器端更新同步(Refresh sync from server only) | 服务器发送所有的数据给客户端,替换客户端的数据 | 第七章五节 |
服务器提醒同步Server Alerted Sync | 服务器提醒客户端执行同步 | 第八章 |
1.4 符合和约定
参考英文版
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD",
"SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY" and "OPTIONAL" in this document are to be interpreted as described in [RFC 2119].
Any reference to components of the Device Information DTD or XML snippets are specified in this type face.
1.4.1 MSC 名称概念
用在消息序列图上面的名称概念如下
l BOX - 一个初始过程或者设备的内部过程
l Hexagon- 开始传输的一个需要条件
l Arrow-代表一个消息或者一个传输过程
2.协议的基础
在此章节,所有的同步类型的特征和需求都将被定义.
2.1 改变日志信息
本协议要求所有设备(客户端设备和服务端设备)能够跟踪他们之间的发生的改变和同步.
他们需要维护数据项的修改日志信息,修改包含替换,增加,删去. 本协议没有规定在设备内部
怎样维护这些日志信息.然而,当同步开始的时候,设备必须知道哪些数据项发生了改变.
为了标识这些数据项,唯一标识符需要使用.不同的操作也需要标识,比喻是替换 增加 删去等
2.1.1 多个设备
如果一个设备要和多个设备同步,日志信息必须能够表明在上一次同步之前所有的修改.
2.2 同步锚点的语法
2.2.1 数据库的同步锚点
为了清楚的同步,本协议使用数据库的同步锚点(参考定义),有两个同步锚点:Last和Next(
参考Mea Information DTD),他们在同步初始化的时候使用.
Last 同步锚点: 表示发送设备发送数据前,发生的一个同步事件,主要记录上一此发生同步的时间戳
Next 同步锚点: 表示当前发送设备发送数据时,发生的同步时间,一般就是当前的时间戳
因此,客户端和服务器相互发送各自的同步锚点,锚点信息包含在Alert命令的Meta元素中.
接收设备必须响应Next锚点,通过stats元素传回给发送设备.
使用同步锚点是规范同步实现,在下以前同步之前,同步服务器需要存储Next锚点.
在一个同步session完成之前,存储的锚点不能被更新.
一个设备不会最发送给其他设备和从其他设备接收任何的SyncML消息时,一个同步session就算完成了,同步在Sync命令级别完成了.但是,传输还没有完成,只有当传输级的通信完成,才能看作同步完成了.如何同步设备之间的通信没有结束,设备不能更新同步锚点.
2.2.1.1 数据库锚点的使用例子
在这个例子中,一个同步客户和服务器同步两次(同步sesssions #1和#2),在同步session #1之后,同步客户的内存被重设,因此,数据库的锚点和同步session #2的锚点步相同,同步服务器发现这个信息,将对客户初始一个慢同步(slow sync).
同步session #1 在上网2001.11.10.10:10:10,上一次同步在2001.09.09.09:09:099(在session #1之前),在这个同步seesion中,没有初始化慢同步,因为锚点是相同的.
同步session #2 在2001.11.11.11:11:11,因为同步客户的内容被从新,服务器初始一个慢同步.
在下图中,描述了两个同步session,仅描述了初始化阶段和同步锚点
例子3 同步锚点的使用
2.2.2 数据项的同步锚点
本协议没有明确的指定如何传输单独的数据项,如何需要这个功能,数据锚点必须在数据项中提供,
vCalendar的序列数字属性和电子日历和日程交换数据格式.
2.3 数据项的ID匹配
本协议是建立在同步服务和同步客户都有自己的数据ID标识,服务器和客户的ID标号可能相同,也可能不相同,因此,服务器必须要维护客户ID(LUID)和服务ID(server ID)指向相同的数据项.
图四显示了一个同步以后的ID匹配的例子,在这个例子中服务端的匹配表分为两个独立的数据表
通常,LUID数据在客户设备端指定,如果服务器增加了一个数据项给客户设备端,客户设备自己指定LUID(设备本地数据项ID),客户端返回这个数据项的LUID给服务器,服务器更新匹配表.
当服务器增加一条数据项给客户设备,如果GUID的长度大于客户端定义的临时GUID,服务器不能把实际的GUID发送给客户,服务器必须用很小的临时GUID,临时GUID在客户端的设备信息文档中定义.
如果服务器修改了一个存在的数据项(这个数据项在客户设备和服务器中都存在),
服务器必须能用客户这个项的LUI标识.客户端修改了数据项,项也是用LUID标识,当修改发送给服务器,服务器能过匹配LUID到GUID通过匹配表.
2.3.1 匹配操作的缓存
在SyncML客户请求一个或多个增加之后,客户端已经完成了这些增加,并且给它们指定了LUID,如果服务器没有明确的规定需要需要一个同步消息的情况下,客户端能够缓存这些LUID的匹配操作.客户端也允许立即给服务器发送匹配操作.
如果匹配项被缓存,在接下来的同步session中,匹配操作被发送给服务器.
在客户端能处理与这些数据项的时候(增加的但是匹配操作被缓存了的数据项),匹配操作必须送出. 如果SyncML服务器有传输控制协议(OBEX),它必须请求一个同步命令的响应.
在获得客户的同步命令之前服务器不能断开连接
2.4 冲突处理
服务器和客户端同时修改相同的数据项的时候会发生冲突,一般在服务设备的同步引擎(sync engine)中解决. 本协议和表示层协议提供的功能告诉客户端已经解决的冲突.
一般认为同步引擎包含在SyncML 服务器中,然而,客户端也可以提供同步引擎处理冲突.
对于后一种情况,服务器仅仅告诉客户端发生了冲突,客户端能够处理这些冲突.
有很多的策略来解决这些冲突,对于常见的策略,SyncML表示层协议提供状态码(status codes).服务器的同步引擎能够解决冲突,并且发送冲突信息和冲突是如何解决的.这些通知信息包含在status元素中.
下面是一个例子描述了服务器发送状态码给客户设备.
<Status>
<CmdID>1</CmdID>
<MsgRef>1</MsgRef>
<CmdRef>2</CmdRef>
<Cmd>Replace</Cmd>
<SourceRef>1212</SourceRef>
<Data>208</Data> <!-- Conflict, originator wins -->
</Status>
如何管理和配置策略,超出了本协议和SyncML表示层协议的范围
2.5 安全
本协议要求支持基本认证和MD5数字签名,服务器和客户端能够交换授权信息.
认证过程参考第三章
2.6地址
2.6.1 设备和服务的地址
SyncML规范使用URI 标志对SyncML SyncHdr头元素中的设备和服务地址进行编址。
设备通常;连接Internet,要参考URI基础的编址,源可能是:
<Source>
<LocURI>http://www.syncml.org/sync-server</LocURI>
</Source>
临时连接的设备,可能是不用它自己的标识机制表示,移动手机设备的源可能是:
<Source>
<LocURI>IMEI:493005100592800</LocURI>
</Source>
如何使用这只类型的编码机制,在传输层和设备和服务地址是比匹配的。
2.6.1.1 RespURI和Re-direction 状态码的用法
在SyncML协议规范中第一了RespURI元素。本协议要求设备支持接收RespURI元素,但是可以不支持Re-direction(3xx) 状态码。
2.6.2 数据库的编址
在SyncML 操作中的数据库编址使用的是URI机制,对客户端和服务端的编址可以使用绝对和相对的URI 。在两种情况下,服务端数据库的source元素可以如下:
<Sync>...
<Target>
<LocURI>./calendar/james_bond</LocURI>
</Target>
...</Sync>
<Sync>
<Target>
<LocURI>http://www.syncml.org/sync-server/calendar/james_bond</LocURI>
</Target>
...</Sync>
2.6.3 数据项的编址
在SyncML Item元素中的数据项的编址是使用URI-based 。可以使用相对的URI‘s。
一个数据项的源元素可以如下:
<Item>...
<Source>
<LocURI>101</LocURI>
</Source>
...</Item>
2.7交换设计的能力
本协议提供了在同步初始化阶段交换设备的能力(参考第四章), sync 客户或sync 服务器都可以发送交换请求。当最初的同步完成前或客户更新了静态设备信息,Sync 客户必须送它 的设备信息到服务器。如果服务端要求客户端的设备信息,客户端必须把它的设备信息发送给服务器。这个客户应该并且支持接受服务器设备信息。如果客户端要求 服务端的设备信息,服务端必须发送它的设备信息给客户端,服务器必须支持功能获得和处理客户设备信息,这些设备信息可以是客服端发送的或者是服务端请求 的。
实施考虑。设备信息的交换信息可能需求传送大相当数量数据。因而, 每次当同步初始化时,设备应该避免请求交换。另外, 如果客户端确切其它设备不可能支持它设备能力,客户端应该考虑是否它需要寄发所有设备具体数据。
如果客户端清楚的表明它不支持这个vCard3.0 内容格式, 服务器支持vCard3.0,但服务器不应该送vCard3.0 的属性信息。
2.8 设备内存管理
本协议与Meta信息DTD 提供指定设备数据库的动态内存或在设备上面坚持存贮的内存的能力。有多少剩余的内存可以被使用。每次同步的时候都可以交换这些设备能力。当sync 初始化完成时,静态内存能力被交换。 (参见第二章七节和第四章) 。
虽然,同步客户和服务器发送内存能力是可选的,同步客户应该送这些并且同步服务器也可以。
不同的类型的内存能力的用法是依赖于设备的存贮模型。下面有一个例子说明怎样表示一个设备上的日历数据库的动态内存的能力, 当发送同步命令:
<Sync>
<CmdID>1</CmdID>
<Target><LocURI>./calendar/james_bond</LocURI></Target>
<Source><LocURI>./dev-calendar</LocURI></Source>
<Meta>
<Mem xmlns='syncml:metinf'>
<FreeMem>8100</FreeMem>
<!--Free memory (bytes) in Calendar database on a device -->
<FreeId>81</FreeId>
<!--Number of free records in Calendar database-->
</Mem>
</Meta>
<Replace>
...
</Replace>
...
</Sync>
在同步命令的Meta元素的数据库具体内存元素必须同在同步命令中的Source元素指定的源数据库相关联在一起来源数据库指定在Sync 命令的来源元素。
因而, 这个数据库不在在Meta 元素中指定。
2.8 包中多条消息
本协议提供在多个SyncML消息中传递一个SyncML包。如果一个SyncML 包对于一条SyncML 消息太大,这种情况可能是由于传输协议或者小设备的原因导致的。如果在多条SyncML 消息中传送一个SyncML 包,最后一条消息必须包含Fianl元素,属于这个包的其他消息一定不要包含Final元素。当一个包中所有的命令发送完以后,Final元素必须包含在这些命令之后。如果一个包中的其他项没有结束,则不能包含Final元素。例如, 如果服务器仍然送这个包#4给客户, 这个客户不能关闭包裹#5早于在接受包# 4的最后一条消息前。如果一个错误发送,不能用Final元素表明逻辑阶段没有完成。
如果设备接受最后的一条消息,这条消息包含了Sync元素但是缺少了Final元素,设备必须能够在下条消息中处理这种情况, 下条消息中中有其它 Sync 元素同步相同的数据库。
接受包含多种消息的SyncML包的设备必须能够要求更多消息。要求更多消息是通过发送Alert命令,并且指定alert 代码。222代码将被返回或者有其他的SyncML命令返回,333 alert代码可以被省去。
这发生由送一个机敏命令与一个具体机敏代码, 222 回到这个包裹的创作者, 或如果有其它SyncML 命令被送作为反应, 机敏命令与这个222 机敏代码也许被省去。在接受这则消息以后包含最后的元素, 机敏命令不能被使用。在收到包含了Final元素的消息以后,Alert命令不能在使用。
如果发送了错误,同步将被终止,不要在发送更多的消息。
当包的发送者要求更多的消息的时候,包的接收者开始发送它的下一个包。在第三章第七节,它被指定在接受到包含Final元素的消息之前,命令或元素被允许发送,包含Final元素的消息和发送命令或元素的消息属于同一个包。
下面这个例子说明了一个同步客户在多个消息(2个消息)中发送包#3和服务器在多个消息(2个消息)中发送包#4。
2.10 大对象的处理
本协议提供方法同步那些大小超出在一则消息之内传送的对象。通过分割对象成能是否消息能够被传送的小部分,使用< MoreData / > 元素告诉接收者,这个大块数据项目还没有完成,还会有其他的部分传送过来。
当接收者接收到一个包含<MoreData/> 元素的对象,它必须响应“214-小部分对象收到并且缓存了”和,并且,如果不需要发送其他的命令,使用alert 222(在第二章第九部分)机制要求下一条消息。
能够在一条消息中传输的对象不能使用<MoreData/>元素,分割成几个小部分的对象,处理最后一条传送消息中不包含<MoreData/>元素,其他的传送消息都需要包含。
发送者不能增加新的数据对象到任何一条消息知道前面的数据对象发送完成。分割成小部分的对象必须连续的发送,新的命令或者新的数据项不能在中间发送。
2.1 没有单独初始化的同步
同步可以在没有单独初始化的情况下开始(参考第四章的初始化同步), 初始化可以和同步同时进行,这样可以减少传送SyncML 消息的数量.
如果同步没有初始化过程,在包#1(客户发送的)中的Alert命令将放置在包#3中,包#3中同时也放置了Sync命令. 在包#2中的Alert命令(服务端发送的)将放置在包#4中,在包#4中同时也放置了Sync命令.
同步服务器必须能够处理这两种情况:在同步命令前没有单独的初始化和在同步命令前有单独的初始化.
参考附件中的例子.
2.11.1 强壮性和安全性
如果客户决定采用没有单独的初始化过程的同步,下面的一些事情需要考虑:
在服务器获得客户的同步锚点前,客户发送修改命令给服务器,这种情况下,获得锚点,如果服务端请求一个慢同步,那么,客户端需要发送所有的数据.
客户端在没有收到服务器的同步锚点之前,客户发送了客户端的修改.如果客户需要请求一个慢同步,客户早期(在包#3中)发送的数据,可以不用在发送给服务器,但是所有的数据必须发送给服务器.
客户发送给服务器它的修改在有任一种可能性使服务器送它的认证(如果必须) 到这个客户。即, 客户不可能肯定是正确服务器通信。
2.12 忙信号
如何服务器能够接收客户的修改数据,但是,它不能在合理的时间内处理客户的这个请求,服务器应该发送忙的status 码给客户.
客户端收到服务器的忙信号以后,客户可以在晚些时候要求同步或者重新开始一个同步.如何客户重新开始一个同步,那么客户的Last 同步锚点一定不能被更新.
如果服务器发送了忙status码给客户后,没有收到客户的请求,那么服务器必须假设它将从头开始同步,服务器不能更新Last 锚点,也不能修改客户的Next锚点.
2.12.1 服务器的忙status
服务器通过发送忙status 包给客户通知服务器正忙.这个包可以在完全接收任何一个包之前. 在客户请求包中的Syncbody部分有数据项和其它命令,忙status 包不能返回他们的状态信息.
1.在忙status包中的元素的要求如下:
VerDTD元素的值必须四'1.1';
VerProto元素的值必须是'SyncML/1.1';
Session ID 必须能够表明一个同步Sesson 的ID
MsgID 必须明确的表明它属于一个session 的第几个包消息(服务端发送给客户的)
Target 元素指定目标设备
Source 元素指明原设备或者服务
2.对SyncHdr元素的status元素必须包含在SyncBody.
status 码(101 正在处理)必须返回,这个状态码是位SyncHdr的.
2.12.1.1 Example of Busy Status
<SyncML>
<SyncHdr>
<VerDTD>1.1</VerDTD>
<VerProto>SyncML/1.1</VerProto>
<SessionID>1</SessionID>
<MsgID>2</MsgID>
<Target><LocURI>IMEI:493005100592800</LocURI></Target>
<Source><LocURI>http://www.syncml.org/sync-server</LocURI></Source>
</SyncHdr>
<SyncBody>
<Status>
<CmdID>1</CmdID>
<MsgRef>2</MsgRef><CmdRef>0</CmdRef><Cmd>SyncHdr</Cmd>
<TargetRef>http://www.syncml.org/sync-server</TargetRef>
<SourceRef>IMEI:493005100592800</SourceRef>
<Data>101</Data> <!--Statuscode for Busy-->
</Status>
</SyncBody>
</SyncML>
2.12.2 客户的结果(Result) Alert 命令
结果Alert命令是客户发送给服务器要求上一条消息的结果的命令.客户通过发送结果Alert命令给服务器.
在包中消息的要求如下:
1.在SyncHdr元素中的元素要求如下:
VerDTD元素的值必须四'1.1';
VerProto元素的值必须是'SyncML/1.1';
Session ID 必须能够表明一个同步Sesson 的ID
MsgID 必须明确的表明它属于一个session 的第几个包消息(服务端发送给客户的)
Target 元素指定目标设备或者服务
Source 元素指明原设备
2.alert元素必须包含在SyncBody中,Alert元素的要求如下:
CmdID是需要的
Item 元素指明服务和客户设备
Data 元素用来包含Alert 码,Alert码为 '221'
3. Final元素一定不要包含.
如果服务器收到客户的结果Alert时,服务还是忙,那么服务器必须返回'101'status给客户,这个状态码对于客户发送的消息的SyncHdr和Alert命令.
2.12.2.1 Example of Result Alert
<SyncML>
<SyncHdr>
<VerDTD>1.1</VerDTD>
<VerProto>SyncML/1.1</VerProto>
<SessionID>1</SessionID>
<MsgID>3</MsgID>
<Target><LocURI>http://www.syncml.org/sync-server</LocURI></Target>
<Source><LocURI>IMEI:493005100592800</LocURI></Source>
</SyncHdr>
<SyncBody>
<Alert>
<CmdID>1</CmdID>
<Data>221</Data>
<Item>
<Target><LocURI>http://www.syncml.org/sync-server</LocURI></Target>
<Source><LocURI>IMEI:493005100592800</LocURI></Source>
</Item>
</Alert>
</SyncBody>
</SyncML>
3.鉴权
在这章中,使用 basic 和 MD5 数字签名的授权过程. 这两种方式设备都必须支持.
3.1 鉴权请求
如果返回给一个请求(消息或者命令)的响应码是401(没有授权)或者407(授权需要),那么这个请求是要求授权的.在这中情况下,返回给请求的Status命令必须包含包含一个Chal 元素. Chal元素包含对请求资源的授权要求.设备可能会使用Cred元素重复这个请求过程.如果这个请求包含了Cred元素,那么返回401码表明授权被拒绝. 客户和服务器都能够要求授权.
如果响应码是401的响应包含和上次响应相同的要求授权信息,并且用户代理已经认证过至少一次,那么,用户应该给响应一些相应的诊断信息.
如果响应码是212(认证通过),那么余下的同步过程不在需要认证了.
在MD5数字签名的认证情况下,Chal元素能过被返回.在Chal元素中next nonce 熟悉必须用被使用,表明下个同步session 开始的时候使用的签名.
如果一个请求包含了安全认证并且响应码是200(同步命令已经成功完成),那么相同的认证必须在下一个同步请求中发送.如果Chal元素被包含并且要求使用MD5数字签名认证.如何包含了Chal元素并且需要使用MD5数字签名,一个新的数据签名必须被创建,同样也是MD5的数据签名.在使用MD5数据签名认证的情况下,Chal元素能够被返回.单下个请求开始的时候,Chal中的next nonce必须被使用.
当一个授权已经发生,在整个seesion过程中必须使用相同的授权类型.
授权失败(用户ID和密码错误或者需要一个授权)的要求如下:
响应消息表明服务层的授权失败,并且,响应消息必须并且仅仅任包含Status命令(Put,get命令不能包含在响应中),status 命令必须提供给收到的请求的每一个命令.
在session还要继续的情况下,包含了合适的认证的下一条消息必须包含一个
对SyncHdr的status,和前一条消息必须是相同的Session ID,当授权失败RespURI被指定的情况下,消息必须送给RespURI.
3.2 授权
当收到包含了401或者407的响应以后,请求如果需要重复发送,那么,请求必须包含Cred元素.另外,设备可以把包含chal元素的请求第一个发送,如果授权被配置成需要的.Cred 元素的内容在文档[1]中说明.授权类型独立请求或者预先配置.
3.3 服务层授权
当需要授权时候,协议仅仅支持服务层的授权(在SyncHdr元素).设备必须支持服务层的授权. 使用SyncHdr元素的Cred元素和Status命令完成服务层的授权.在status命令中,授权请求被传送.授权可以是双方向的,客户可以授权给服务器,服务器也可以授权给客户.
3.4 数据库层的授权
1.本规范规定设备可以支持数据库层的授权.通过Alert元素中的Cred元素和和sync命令和status完成.在status命令中包含了早期定义的请求信息.认证可以是双方向的,客户可以授权给服务器,服务器也可以授权给客户.
3.5 授权例子
3.5.1 Basic授权请求
在这个例子中,可以试在没有认证信息的情况初始化同步,服务端先客户请求服务层的认证信息.客户必须重发包#1,包#1中包含了认证信息.服务接收认证并且seesoin被授权.在这个例子中,SyncBody的内容没有被包含.
Pkg #1 from Client
<SyncML>
<SyncHdr>
<VerDTD>1.1</VerDTD>
<VerProto>SyncML/1.1</VerProto>
<SessionID>1</SessionID>
<MsgID>1</MsgID>
<Target><LocURI>http://www.syncml.org/sync-server</LocURI></Target>
<Source><LocURI>IMEI:493005100592800</LocURI></Source>
</SyncHdr>
<SyncBody>
...
</SyncBody>
</SyncML>
Pkg #2 from Server
<SyncML>
<SyncHdr>
<VerDTD>1.1</VerDTD>
<VerProto>SyncML/1.1</VerProto>
<SessionID>1</SessionID>
<MsgID>1</MsgID>
<Target><LocURI>IMEI:493005100592800</LocURI></Target>
<Source><LocURI>http://www.syncml.org/sync-server</LocURI></Source>
</SyncHdr>
<SyncBody>
<Status>
<CmdID>1</CmdID>
<MsgRef>1</MsgRef><CmdRef>0</CmdRef><Cmd>SyncHdr</Cmd>
<TargetRef>http://www.syncml.org/sync-server</TargetRef>
<SourceRef>IMEI:493005100592800</SourceRef>
<Chal>
<Meta>
<Type xmlns='syncml:metinf'>syncml:auth-basic</Type>
<Format xmlns='syncml:metinf'>b64</Format>
</Meta>
</Chal>
<Data>407</Data> <!--Credentials missing-->
</Status>
...
</SyncBody>
</SyncML>
Pkg #1 (with credentials) from Client
<SyncML>
<SyncHdr>
<VerDTD>1.1</VerDTD>
<VerProto>SyncML/1.1</VerProto>
<SessionID>1</SessionID>
<MsgID>2</MsgID>
<Target><LocURI>http://www.syncml.org/sync-server</LocURI></Target>
<Source><LocURI>IMEI:493005100592800</LocURI></Source>
<Cred>
<Meta><Type xmlns='syncml:metinf'>syncml:auth-basic</Type></Meta>
<Data>QnJ1Y2UyOk9oQmVoYXZl</Data> <!—base64 formatting of
"userid:password"-->
</Cred>
</SyncHdr>
<SyncBody>
...
</SyncBody>
</SyncML>
Pkg #2 from Server
<SyncML>
<SyncHdr>
<VerDTD>1.1</VerDTD>
<VerProto>SyncML/1.1</VerProto>
<SessionID>1</SessionID>
<MsgID>2</MsgID>
<Target><LocURI>IMEI:493005100592800</LocURI></Target>
<Source><LocURI>http://www.syncml.org/sync-server</LocURI></Source>
</SyncHdr>
<SyncBody>
<Status>
<CmdID>1</CmdID>
<MsgRef>1</MsgRef><CmdRef>0</CmdRef><Cmd>SyncHdr</Cmd>
<TargetRef>http://www.syncml.org/sync-server</TargetRef>
<SourceRef>IMEI:493005100592800</SourceRef>
<Data>212</Data> <!--Authenticated for session-->
</Status>
...
</SyncBody>
</SyncML>
3.5.2 MD5数据签名认证请求
在这个例子中,客户试着在没有任何的认证的情况下开始初始化同步(包#1),
服务器向客户请求服务层的认证.认证类型是MD5.客户必须重新发送包含了认证
信息的包#1,服务器接收认证,session被授权.服务器发送下一个nonce 认证给
客户,客户将使用她在下一个同步session 开始的时候是用nonce的认证.
在这个例子中,SyncBody的内容没有显示.
Pkg #1 from Client
<SyncML>
<SyncHdr>
<VerDTD>1.1</VerDTD>
<VerProto>SyncML/1.1</VerProto>
<SessionID>1</SessionID>
<MsgID>1</MsgID>
<Target><LocURI>http://www.syncml.org/sync-server</LocURI></Target>
<Source>
<LocURI>IMEI:493005100592800</LocURI>
<LocName>Bruce2</LocName> <!-- userId -->
</Source>
</SyncHdr>
<SyncBody>
...
</SyncBody>
</SyncML>
Pkg #2 from Server
<SyncML>
<SyncHdr>
<VerDTD>1.1</VerDTD>
<VerProto>SyncML/1.1</VerProto>
<SessionID>1</SessionID>
<MsgID>1</MsgID>
<Target><LocURI>IMEI:493005100592800</LocURI></Target>
<Source><LocURI>http://www.syncml.org/sync-server</LocURI></Source>
</SyncHdr>
<SyncBody>
<Status>
<CmdID>1</CmdID>
<MsgRef>1</MsgRef><CmdRef>0</CmdRef><Cmd>SyncHdr</Cmd>
<TargetRef>http://www.syncml.org/sync-server</TargetRef>
<SourceRef>IMEI:493005100592800</SourceRef>
<Chal>
<Meta>
<Type xmlns=’syncml:metinf’>syncml:auth-md5</Type>
<Format xmlns=’syncml:metinf’>b64</Format>
<NextNonce xmlns=’syncml:metinf’>Tm9uY2U=</NextNonce>
</Meta>
</Chal>
<Data>407</Data> <!--Credentials missing-->
</Status>
...
</SyncBody>
</SyncML>
Pkg #1 (with credentials) from Client
<SyncML>
<SyncHdr>
<VerDTD>1.1</VerDTD>
<VerProto>SyncML/1.1</VerProto>
<SessionID>1</SessionID>
<MsgID>2</MsgID>
<Target><LocURI>http://www.syncml.org/sync-server</LocURI></Target>
<Source><LocURI>IMEI:493005100592800</LocURI></Source>
<Cred>
<Meta><Type xmlns='syncml:metinf'>syncml:auth-md5</Type></Meta>
<Data> Zz6EivR3yeaaENcRN6lpAQ==</Data>
<!-- Base64 coded MD5 for user “Bruce2”, password “OhBehave”,
nonce “Nonce” -->
</Cred>
</SyncHdr>
<SyncBody>
...
</SyncBody>
</SyncML>
Pkg #2 from Server
<SyncML>
<SyncHdr>
<VerDTD>1.1</VerDTD>
<VerProto>SyncML/1.1</VerProto>
<SessionID>1</SessionID>
<MsgID>2</MsgID>
<Target><LocURI>IMEI:493005100592800</LocURI></Target>
<Source><LocURI>http://www.syncml.org/sync-server</LocURI></Source>
</SyncHdr>
<SyncBody>
<Status>
<CmdID>1</CmdID>
<MsgRef>1</MsgRef><CmdRef>0</CmdRef><Cmd>SyncHdr</Cmd>
<TargetRef>http://www.syncml.org/sync-server</TargetRef>
<SourceRef>IMEI:493005100592800</SourceRef>
<Chal>
<Meta>
<Type xmlns=’syncml:metinf’>syncml:auth-md5</Type>
<Format xmlns=’syncml:metinf’>b64</Format>
<NextNonce xmlns=’syncml:metinf’>LG3iZQhhdmKNHg==</NextNonce>
<!—This nonce is used at the next session.-->
</Meta>
</Chal>
<Data>212</Data> <!—Authenticated for session-->
</Status>
...
</SyncBody>
</SyncML>
4、同步初始化
实际的同步过程需要初始同步(参考章节5-7),初始同步过程可以传送
和执行同步命令(sync commands)。
在初始同步前,同步服务器(SyncML server)可能会提示同步客户同步。
但是初始同步过程不能忽略。
初始同步的目的有:
1、服务器和客户端在SyncML级别进行权限认证。
2、表明使用哪个数据库和使用什么协议。
3、交换服务器和客户设备的处理能力
前两点通过SyncML表示层协议中的Alert命令实现。服务器和客户设备必须支持实现上面的功能。
服务器和客户设备交换能力可以通过SyncML表示层协议中的Put、Get命令和设备的DTD信息实现。
初始同步过程如下:在实际的同步信息中包含了有些处理过程(一些响应)
上面图像中的箭头表示SyncML包。SyncML包可以包含一个或多个消息(messages)。
这个过程中的属于的包共同一个Session,就是说有相同的Session ID号。
每个包的目的和需要将在下节介绍。
4.1 客户端(Client)的初始化请求
前面的章节提到,客户端在初始化的时候,(Client)通知服务器需要同步哪个数据库和使用哪种的同步类型。
同时,客户端还能包含授权信息和服务能力(service capabilities。
在Alert命令中指示哪个数据库需要同步。每一个数据库需要使用一个单独的Alert命令。
另外,Alert命令可以去exchange the sync anchors. 如果需要授权信息,必须要包含包头
(SyncHdr)中包含Cred元素。数据可以是Basic或者MD5加密的数字签名。
可以通过在包体(SyncBody)元素中使用Put命令来交换服务器和设备的能力。
客户端必须要服务和设备信息,这些信息可以从设备(Device)DTD中获得。
客户端发送给服务器的同步初始化包(在图6 Pkg#1)的详细需求如下:
4.在SyncHdr(包头)元素中的要求如下:
A.VerDTD元素的值必须是‘1.1’。
B.必须VerProto元素来制定使用的协议和协议版本,其值必须为‘SyncML/1.1’
C. 必须制定同步的session ID
D. 必须使用Msgid清晰的表明消息属于一个同步session(sync session)
E、如果需要认证的,必须包含Cred元素。
5. 在指明需要使用哪些数据库的时候,使用Alert元素。Alert元素需包含在SyncBody元素中,具体的要求如下:
A. 必须使用CmdID元素
B.Alert元素必须有响应。
C.在Alert元素中必须包含Data元素。Data元素的值表明Alert代码。具体参考Alert Codes。
D. item元素中的Target元素表明目标数据源
E.item元素中的Source元素表明客户的数据源
F.客户的同步(sync anchors)必须包含在previous 和 current 同步(anchors),在Meta元素中包含同步(anchors)
6. 在服务端和客户端交换服务能力,如何是客户发给服务,需要在SyncBody元素中使用Put命令。
A.必须要CmdID
B.在Put命令的Meta元素中必须包含Type元素指明MetaInf DTD
C.在Item元素中的Source元素必须有一个值为'./devinf11'.
D.Data元素中包含的是设备和服务信息。
7.服务端向客户发送服务能力,需要在SyncBody中使用Put命令。
A.必须要CmdID
B.在get命令的Meta元素中必须包含Type元素指明MetaInf DTD
C.在Item元素中的Target元素必须有一个值为'./devinf11'.
D.Data元素中包含的是设备和服务信息。
8、必须包含Final元素表明这条信息结束
4.1.1 Example of Sync Initialization Package from Client
<SyncML>
<SyncHdr>
<VerDTD>1.1</VerDTD>
<VerProto>SyncML/1.1</VerProto>
<SessionID>1</SessionID>
<MsgID>1</MsgID>
<Target><LocURI>http://www.syncml.org/sync-server</LocURI></Target>
<Source><LocURI>IMEI:493005100592800</LocURI></Source>
<Cred> <!--The authentication is optional.-->
<Meta><Type xmlns='syncml:metinf'>syncml:auth-basic</Type></Meta>
<Data>QnJ1Y2UyOk9oQmVoYXZl</Data> <!--base64 formatting of "userid:password"-->
</Cred>
<Meta> <!--The Meta is now used to indicate the maximum SyncML message size, which
client can receive.-->
<MaxMsgSize xmlns='syncml:metinf'>5000</MaxMsgSize>
</Meta>
</SyncHdr>
<SyncBody>
<Alert>
<CmdID>1</CmdID>
<Data>200</Data> <!-- 200 = TWO_WAY_ALERT -->
<Item>
<Target><LocURI>./contacts/james_bond</LocURI></Target>
<Source><LocURI>./dev-contacts</LocURI></Source>
<Meta>
<Anchor xmlns='syncml:metinf'>
<Last>234</Last>
<Next>276</Next>
</Anchor>
</Meta>
</Item>
</Alert>
<Put>
<CmdID>2</CmdID>
<Meta><Type xmlns='syncml:metinf'>application/vnd.syncml-devinf+xml</Type></Meta>
<Item>
<Source><LocURI>./devinf11</LocURI></Source>
<Data>
<DevInf xmlns='syncml:devinf'>
<Man>Big Factory, Ltd.</Man>
<Mod>4119</Mod>
<OEM>Jane's phones</OEM>
<FwV>2.0e</FwV>
<SwV>2.0</SwV>
<HwV>1.22I</HwV>
<DevId>1218182THD000001-2</DevId>
<DevTyp>phone</DevTyp>
<DataStore>
<SourceRef>./contacts</SourceRef>
<DisplayName>Phonebook</DisplayName>
<MaxGUIDSize>32</MaxGUIDSize>
<Rx-Pref>
<CTType>text/x-vcard </CTType>
<VerCT>2.1</VerCT>
</Rx-Pref>
<Tx-Pref>
<CTType>text/x-vcard</CTType>
<VerCT>2.1</VerCT>
</Tx-Pref>
</DataStore>
<CTCap>
<CTType>text/x-vcard</CTType>
<PropName>BEGIN</PropName>
<ValEnum>VCARD</ValEnum>
<PropName>END</PropName>
<ValEnum>VCARD</ValEnum>
<PropName>VERSION</PropName>
<ValEnum>2.1</ValEnum>
<PropName>N</PropName>
<PropName>TEL</PropName>
<ParamName>VOICE</ParamName>
<ParamName>CELL</ParamName>
</CTCap>
<SyncCap>
<SyncType>01</SyncType>
<SyncType>02</SyncType>
</SyncCap>
</DevInf>
</Data>
</Item>
</Put>
<Get>
<CmdID>3</CmdID>
<Meta><Type xmlns='syncml:metinf'>application/vnd.syncml-devinf+xml</Type></Meta>
<Item>
<Target><LocURI>./devinf11</LocURI></Target>
</Item>
</Get>
<Final/>
</SyncBody>
</SyncML>
5、两方同步
两方同步是最普通的一种同步类型,客户端和服务端都需要相互交换修改了的
数据。客户端通常是一种设备,首先提交修改信息。服务端通过比较客户提交
的修改信息,然后统一服务端的数据。服务器发送服务端的修改数据给客户端
,客户端根据这些数据统一客户端的数据。
上图的箭头代表SyncML包,SyncML包可能保护一条或多条消息。上面的数据包
是在一个session中,也就是这些SyncML的session ID是相同的。
上面每个包的目的和要求将在下个章节介绍。
如何没有独立的同步初始化,上图中包的编号可能和时间的包编号不一样。
5.1 客户端发送修改给服务器
为了同步,客户端需要把客户端的从上次同步以后的所有修改数据发送给服务器。发送了这个同步包以后的所有客户端的修改数据,必须在下一个session中再发送(注意,是下一次同步过程了。)
客户端发送给服务端的包的要求:
1.在SyncHdr元素中的元素要求:
a.VerDTD的值必须是'1.1'
b.VerProto元素的值必须是'SyncML/1.1'
c.Session ID 必须表示一个同步session的ID
d.MsgID必须能明确的表明属于哪一个从客户端发送给服务端的session
e.Target元素必须指明目标地址
f.Source元素必须指明源地址
2.客户端发送的Alert命令必须有Status返回.
a.服务器没有授权使用的服务,同步将发生错误.如何有错误发生,客户端必须返回错误信息
b.服务器的下一个同步猫点必须保护在Data元素中.
3.服务器发送设备信息给客户端,客户端应该处理这些设备信息,Status必须返回给服务器,在Package #2收到前可以被发送.
4.如果服务器要求客户端的设备信息,Results元素必须被发送,在Package #2
收到前可以被发送.
a.Type 元素的MetaInf DTD必须保护在Meta元素中.
b.在Results元素中的Source元素的值必须是'./devinf11'
5.Sync元素必须被包含在SyncBody元素中,要求如下:
a.需要CmdID元素
b.Sync命令的响应是需要的
c.Target指明目标数据库
d.Source指明源数据库
e.自由内存应该在Meta元素中指定,只用内存可以是源数据库中的自由内存
数量或者是客户设备的自由内存数量,这些信息只能在一个包中的第一条
消息中发送
6.在客户端的修改中,操作元素的要求如下:
a.CmdID是需要的
b.这些操作必须要有响应
c.Source 元素必须包含,指明LUID,包含在数据项的Item元素中.
d.MetaInf DTD的Type 元素必须包含
e.如果不是deletion操作,操作数据必须在Data元素中传送
7.Final元素必须包含,在包的最后,表示这是最后的消息
5.2 服务端发送给客户端的修改
发送给客户端的同步包(图7包4)有如下的目的:
u 通知客户端同步分析的结果.
u 通知服务端的修改数据
在发送这个包之后完成的服务端的任何一个修改,都必须在下一个同步
session中同步,不能把这些修改数据做为这次同步的子包.
1.同步包的要求如下:
a VerDTD元素的值必须是'1.1';
b.VerProto元素的值必须是'SyncML/1.1'
c.必须包含Sesion ID表示session的ID号.
d.MsgID 必须明确的指定属于那个session ID.
e.Target必须指定目标设备
f.Source元素必须指明源设备和服务
2.如果客户端需要,Status元素必须不包含在SyncBody中,表明客户端发送数据处理后返回的状态.数据项的Status信息在包3完全接收前发送.
3.Sync 元素必须包括在SyncBody, 如果没有及早发生的错误,这些错误能防止服务器处理sync 分析和送它的修改回到客户。 Sync 元素, 有以下要求:
1. CmdID元素是需要的
2. Syn 命令需要响应
3. Target元素指向目标数据库
4. Source元素指向源数据库
4.在前一次同步以后的所有服务端的修改,他们需要操作元素(Replace,Delete和Add)在sync元素中.
1. CmdID元素是需要的
2. 这些操作需要响应
3. 如果操作是增加操作(addtion),Source定义一个临时的数据项的GUID.
如果不是增加操作(addtion),Source必须不能包含.
4. 如果不是增加操作(addtion),Target元素必须包含定义一个LUID,
如果是增加操作(addtion),Target元素必须不能包含.
5. MetaInfo DTD中的Type元素必须包含在Meta元素中指明数据项的类型.
在一个操作内或一个数据项内可以被使用.
5.Final元素必须包含,表明这是包中的最后一条消息.
<SyncML>
<SyncHdr>
<VerDTD>1.1</VerDTD>
<VerProto>SyncML/1.1</VerProto>
<SessionID>1</SessionID>
<MsgID>2</MsgID>
<Target><LocURI>IMEI:493005100592800</LocURI></Target>
<Source><LocURI>http://www.syncml.org/sync-server</LocURI></Source>
</SyncHdr>
<SyncBody>
<Status>
<CmdID>1</CmdID>
<MsgRef>2</MsgRef><CmdRef>0</CmdRef><Cmd>SyncHdr</Cmd>
<TargetRef>http://www.syncml.org/sync-server</TargetRef>
<SourceRef>IMEI:493005100592800</SourceRef>
<Data>200</Data>
</Status>
<Status><!--This is a status for the client modifications to the server.-->
<CmdID>2</CmdID>
<MsgRef>2</MsgRef><CmdRef>3</CmdRef><Cmd>Sync</Cmd>
<TargetRef>./contacts/james_bond</TargetRef>
<SourceRef>./dev-contacts</SourceRef>
<Data>200</Data> <!--Statuscode for Success-->
</Status>
<Status>
<CmdID>3</CmdID>
<MsgRef>2</MsgRef><CmdRef>4</CmdRef><Cmd>Replace</Cmd>
<SourceRef>1012</SourceRef>
<Data>200</Data> <!--Statuscode for Success-->
</Status>
<Sync>
客户的数据更新状态
客户给服务器的数据更新状态包包含呢客户更新数据的结果信息和新数据项目的LUID,LUID和临时的GUID的匹配操作也要送给服务器.
如果服务器表示它不需要最后一个包的响应,客户可以不发送修改信息包给服务器.如果客户不打算发送这条消息,它必须能够在下次同步前缓存这些Map操作.可以也可以发送这些修改状态给服务器,即使服务器没有要求客户发送.
在包里的消息的要求如下:
在SyncHdr元素中的要求如下:
A.VerDTD元素的值必须四'1.1';
B. VerProto元素的值必须是'SyncML/1.1';
C. Session ID 必须能够表明一个同步Sesson 的ID
D. MsgID 必须明确的表明它属于一个session 的第几个包消息(服务端发送给客户的)
E.Target 元素指定目标设备或者服务
F.Source 元素指明原设备
2.如果服务器请求,status元素必须包含在SyncBody元素中.它表明客户修改数据的状态.statua信息可以在包#4完全结束前发送.
3.如果客户已经处理呢服务器的修改到自己的数据库中,在SyncBody元素中必须包含Map元素.操作了一个数据库,就必须有一个Map操作与之对应,这个命令必须在包#4完全结束后发送.
A. CMDID是需要的
B. 在Map元素中Source和Target元素是需要
C.对Map 操作需要有响应
D.Map元素的数据项中包含客户的LUID和服务端ID(临时的GUID)
发送给服务器的数据更新状态的例子
<SyncML>
<SyncHdr>
<VerDTD>1.1</VerDTD>
<VerProto>SyncML/1.1</VerProto>
<SessionID>1</SessionID>
<MsgID>3</MsgID>
<Target><LocURI>http://www.syncml.org/sync-server</LocURI></Target>
<Source><LocURI>IMEI:493005100592800</LocURI></Source>
</SyncHdr>
<SyncBody>
<Status>
<CmdID>1</CmdID>
<MsgRef>2</MsgRef><CmdRef>0</CmdRef><Cmd>SyncHdr</Cmd>
<TargetRef>IMEI:493005100592800</TargetRef>
<SourceRef> http://www.syncml.org/sync-server </SourceRef>
<Data>200</Data>
</Status>
<Status>
<CmdID>2</CmdID>
<MsgRef>2</MsgRef><CmdRef>4</CmdRef><Cmd>Sync</Cmd>
<TargetRef>./dev-contacts</TargetRef>
<SourceRef>./contacts/james_bond</SourceRef>
<Data>200</Data>
</Status>
<Status>
<CmdID>3</CmdID>
<MsgRef>2</MsgRef><CmdRef>5</CmdRef><Cmd>Replace</Cmd>
<TargetRef>1023</TargetRef>
<Data>200</Data>
</Status>
<Status>
<CmdID>4</CmdID>
<MsgRef>2</MsgRef><CmdRef>6</CmdRef><Cmd>Add</Cmd>
<SourceRef>10536681</SourceRef>
<Data>200</Data>
</Status>
<Map>
<CmdID>5</CmdID>
<Target><LocURI>./contacts/james_bond</LocURI></Target>
<Source><LocURI>./dev-contacts</LocURI></Source>
<MapItem>
<Target><LocURI>10536681</LocURI></Target>
<Source><LocURI>1024</LocURI></Source>
</MapItem>
</Map>
<Final/>
</SyncBody>
</SyncML>
5.4 服务端对可以Map的应答
服务器收到客户的数据的匹配信息,服务器需要对客户的这些信息做出回应.即使客户的最后一个包中没有任何的Map操作,服务器也要和客户进行回应.
包中消息的要求如下:
在SyncHdr元素中的要求如下:
A.VerDTD元素的值必须四'1.1';
B. VerProto元素的值必须是'SyncML/1.1';
C.Session ID 必须能够表明一个同步Sesson 的ID
D.MsgID 必须明确的表明它属于一个session 的第几个包消息(服务端发送给客户的)
E.Target 元素指定目标设备
F.Source 元素指明原设备或者服务
G.消息中一定不能包含响应(response)
2.在SyncBody中必须包含status元素,它用来表明Map操作的状态.这些
能够在包#5完全接收前发送.
3.Final元素必须包含,表明这是包的结尾.
Map应答的例子
<SyncML>
<SyncHdr>
<VerDTD>1.1</VerDTD>
<VerProto>SyncML/1.1</VerProto>
<SessionID>1</SessionID>
<MsgID>3</MsgID>
<Target><LocURI>IMEI:493005100592800</LocURI></Target>
<Source><LocURI>http://www.syncml.org/sync-server</LocURI></Source>
</SyncHdr>
<SyncBody>
<Status>
<CmdID>1</CmdID>
<MsgRef>3</MsgRef><CmdRef>0</CmdRef><Cmd>SyncHdr</Cmd>
<TargetRef>http://www.syncml.org/sync-server</TargetRef>
<SourceRef>IMEI:493005100592800</SourceRef>
<Data>200</Data>
</Status>
<Status>
<CmdID>1</CmdID>
<MsgRef>3</MsgRef><CmdRef>5</CmdRef><Cmd>Map</Cmd>
<TargetRef>./contacts/james_bond </TargetRef>
<SourceRef>./dev-contacts</SourceRef>
<Data>200</Data>
</Status>
<Final/>
</SyncBody>
</SyncML>