PROPFIND
PROPFIND DAV 方法用来获取节点的属性。属性包含 PRESENCE INFORMATION 的一些元组(相关值的集合),如在线状态或所代表的 PRINCIPAL 的显示名称。 对于 RVP,PROPFIND 方法用来从其它 PRINCIPALS 各自的本地服务器上获取其在线状态。此方法还可以用来提取 RVP 实现可能保持的其它属性,如存储在服务器上的永久联系人列表。
PROPFIND 方法检索在所请求的 URL 上定义的属性。PRESENTITY 提交 REQUEST 方法主体中的 propfind XML 元素,此元素说明正在请求的信息。请求特定的属性值、所有属性值或者资源属性名称的列表都是可能的。PRESENTITY 必须提交至少具有一个属性的主体。
如果在检索属性时出现错误,则在响应中必须包括一个相应的错误结果。请求检索一个不存在的属性值是一个错误,并且必须加以记录。如果响应使用一个多状态 XML 元素,则必须返回一个包含 404 Not Found (未找到)状态值的 XML 元素。
每个响应 XML 元素都必须包含一个 href XML 元素,它标识在其上定义了 prop XML 元素中的属性的那个资源。作为一个平面列表返回对具有内部成员的资源的 PROPFIND 请求的结果,此列表中项的次序并不重要。
虽然 DAV 允许 PROPFIND 请求的深度为 0、1 或“无穷大”,其中“无穷大”是缺省值,但是 RVP 要求深度标头为零。这是由于以分布方式实现名称空间时支持其它深度有困难所造成的。如果深度标头不存在或者深度参数不为零,则 RVP PRESENCE SERVICES 会返回状态代码:412 -Precondition Failed(先决条件失败)。
示例
以下示例说明如何检索 RVP PRESENTITY 的显示名属性。
>>请求
PROPFIND /instmsg/aliases/deriks HTTP/1.1
Host: im.example.com
RVP-Notifications-Version: 0.2
RVP-From-Principal: http://im.example.com/instmsg/aliases/deriks
Depth: 0
Content-type: text/xml
Content-Length: XXXX
<?xml version="1.0" ?>
<D:propfind xmlns:D="DAV:"
xmlns:Z="http://schemas.microsoft.com/rvp/">
<D:prop>
<D:displayname/>
</D:prop>
</D:propfind>
>>响应
HTTP/1.1 207 Multi-Status
Content-Type: text/xml
Content-Length: XXXX
RVP-Notifications-Version: 0.2
<?xml version="1.0" ?>
<D:multistatus xmlns:D="DAV:"
xmlns:Z="http://schemas.microsoft.com/rvp/">
<D:response>
<D:href>
http://im.example.com/instmsg/aliases/deriks
</D:href>
<D:propstat>
<D:prop>
<D:displayname>
Derik Stenerson
</D:displayname>
</D:prop>
<D:status>HTTP/1.1 200 OK</D:status>
</D:propstat>
</D:response>
</D:multistatus>
PROPPATCH
PROPPATCH DAV 方法用来设置节点的属性。对于 RVP,此方法可以用来设置 PRESENCE SERVICE 上 PRINCIPAL 的在线状态,或者设置 RVP 系统保持的其它属性。例如,当一个 PRESENTITY “登录”时,PRESENTITY 向 PRESENTITY 的本地服务器发出一个 PROPPATCH 请求,要求将在线状态属性设置为“在线”。
RVP 引入了租用属性的概念。租用属性值会在一段超时过后自动复位为缺省值。在实现合作者列表的在线状态时可以使用它们。例如,PRESENTITY 的在线状态可以将自身复位为离线状态,除非它被刷新。这在客户机崩溃、网络失败或其它必须将 PRESENTITY 状态复位为离线的情况下有用。
尽管 RVP 实现可能禁止租用特定的属性值,但是所有的 RVP 属性都可以具有租用值。PRESENTITIES 获取和设置租用值的方式与处理常规 DAV 属性的方式相同;由 PRESENCE SERVICE 负责识别和解释租用值并强制执行其行为。如果所请求的超时是 RVP PRESENCE SERVICE 的管理策略所不允许的,则 RVP PRESENCE SERVICE 可能拒绝设置属性值。
XML 架构允许在 PROPPATCH 请求和响应中指定一个视图标识符元素,因为某个节点可能有多个 PRESENTITIES 设置属性(即从多台机器登录的用户)。此规范允许将状态更改复制到所有 PRESENTITIES 中,并且允许某些状态是某个 PRESENTITY 所特有的。例如,如果一个 PRINCIPAL 让多个 PRESENTITIES 登录,则任何状态更改为 "busy"(繁忙) 或 "out to lunch"(出去就餐)将导致所有的 PRESENTITIES 都得到此状态更改的通知。然而,如果某个 PRESENTITY 变为离线的或空闲的,则其它的 PRESENTITY 不会得到此状态更改的通知,并且 PRINCIPAL 在不同的 PRESENTITY 上仍然保持在线。
当 PROPPATCH 请求不包含视图标识符时,一个成功的响应会包含一个。此标识符对租用属性和指定此视图标识符的任何后续 PROPPATCH 请求是唯一的。如果具有该视图标识符的所有租用属性到期,则该标识符不再有效,也不应该使用它。
示例
以下示例将一个 RVP PRESENTITY 的在线状态值设置为在线,时间间隔是一小时。除非该属性随后由 PRESENTITY 复位,否则 PRESENCE SERVICE 会在一小时后将在线值转变回离线。
>>请求:
PROPPATCH /instmsg/aliases/deriks HTTP/1.1
Host: im.example.com
RVP-Notifications-Version: 0.2
RVP-From-Principal: http://im.example.com/instmsg/aliases/deriks
Content-Type: text/xml
Content-Length: XXXX
<?xml version="1.0"?>
<D:propupdate xmlns:D="DAV:"
xmlns:Z="http://schemas.microsoft.com/rvp/">
<D:set>
<D:prop>
<Z:state>
<Z:leased-value>
<Z:value>
<Z:online/>
</Z:value>
<Z:default-value>
<Z:offline/>
</Z:default-value>
<Z:timeout>3600</Z:timeout>
</Z:leased-value>
</Z:state>
</D:prop>
</D:set>
</D:propertyupdate>
>>响应:
HTTP/1.1 207 Multi-Status
RVP-Notifications-Version: 0.2
Content-Type: text/xml
Content-Length: XXXX
<?xml version="1.0"?>
<D:multistatus xmlns:D="DAV:"
xmlns:Z="http://schemas.microsoft.com/rvp/">
<D:response>
<D:href>
http://im.example.com/instmsg/aliases/deriks
</D:href>
<D:propstat>
<D:prop>
<Z:state>
<Z:leased-value>
<Z:value>
<Z:online/>
</Z:value>
<Z:default-value>
<Z:offline/>
</Z:default-value>
<D:timeout>
3600
</D:timeout>
</Z:leased-value>
<Z:view-id>3577</Z:view-id>
</Z:state>
</D:prop>
<D:status>HTTP/1.1 200 OK</D:status>
</D:propstat>
</D:response>
</D:multistatus>
实现的考虑事项
RVP PRESENTITY 使用 PROPPATCH 方法以及租用值将其在线状态属性保持为在线。PRESENTITY 使用一些超时值(即 t),使 PRESENCE SERVICE 在经过 t 之后从在线状态属性转变回离线。
如果 PRINCIPAL 继续在 PRESENTITY 上登录,则 PRESENTITY 应该通过在 t 到期之前发出另一个 PROPPATCH 请求,并就属性获得时间间隔为 t 的新租用,以便刷新在线状态属性。因此,如果 t=30 分钟,则 PRESENTITY 应该在大约 29 分钟时发出另一个 PROPPATCH 请求。否则,如果 PRESENTITY 在 30 分钟时发出一个 PROPPATCH 请求,则新的 PROPPATCH 请求可能会在第一次租用到期之后到达 PRESENCE SERVICE。在这种情况下,PRINCIPAL 在线状态的任何订阅者(即在其联系人列表上有此 PRINCIPAL 的所有 WATCHERS )可能获得虚假的通知 — 一个发布给正在注销的 PRINCIPAL,而紧接着的另一个则发布给再次登录的 PRINCIPAL。
几个考虑事项确定应该使用的正确 t 值。如果 PRESENTITY 是 OUT OF CONTACT((失去联系,即 PRESENTITY 计算机崩溃),则 PRESENCE SERVICE 将无法知道 PRESENTITY 已经崩溃,并且在租用到期之前,PRINCIPAL 的在线状态属性一直保持在线。因此,即使 PRINCIPAL 处于离线状态,t 也会限制 WATCHERS 继续将 PRINCIPAL 视为“在线”的时间间隔。将 WATCHER 的联系人列表的状态保持为“新的”,要求 t 较小 — 理想的情况是接近于零。
然而,如果 PRINCIPAL 已登录,则 PRESENTITY 必须重新发出 PROPPATCH 请求,其时间间隔小于 t,以便保持在线状态。因此,每个登录的 PRESENTITY 都会消耗 PRESENCE SERVICE 的资源,因为 PRESENTITY 有效地 "ping" PRESENCE SERVICE,其时间间隔小于 t。甚至在空闲状态下,这也会产生网络通信量。如果一个 PRESENCE SERVICE 上登录了成千上万的 PRESENTITIES,则此负载可以是相当大的。要使 ping 负载得到控制,请将 t 设置为尽可能大的值,以便每个 PRINCIPAL 的经验都不会降级。
注: Exchange 2000 Server Instant Messaging 使用的 ping 时间间隔为 20 分钟。
NOTIFY
RVP NOTIFY 方法,取自 GENA,将异步通知发送到 RVP 节点 — 即通知接收器。当一个 WATCHER A 通过本地服务器向另一个 PRINCIPAL B 上的属性更改发出 SUBSCRIBE 请求时,WATCHER A 会接收到 PRINCIPAL B 上的属性更改的 NOTIFY 请求。
注: 请求主体中的通知 XML 元素包含通知数据。
在不建立较早订阅的情况下也可以发出 NOTIFY 消息。例如,假定具有正确的访问控制权限,则任何实体都可以将 NOTIFY 消息发送到一个组节点(如 http://im.example.com/groups/rec-cycling);组节点无须向任何其它节点发出 SUBSCRIBE 请求。
在一个 intranet 中,NOTIFY 消息通常由本地服务器用来将通知发送到它们的 INSTANT INBOXES。NOTIFY 消息也由 PRESENCE SERVICES 用来将它们托管的 PRESENTITIES 的在线状态更改发送到其它 PRESENCE SERVICES。
因为 NOTIFY 消息的发件人可能要求确认发送,所以一旦完成了发送就会发出成功响应。为了确定 NOTIFY 消息的发件人何时对完成发送和要求确认满意,会出现一个新的 RVP-Ack-Type 标头。此标头可以包含以下字段。
SingleHop 只是在最初收件人(即本地服务器)接收 NOTIFY 消息时,发件人才请求确认。
DeepOr 发件人仅在最终目标之一接收到 NOTIFY 时才请求确认。此用法的一个示例是,当用户将一个 INSTANT MESSAGE 发送给委托人或者打印机缺纸时,要求系统管理员之一得到通知。
DeepAnd 发件人仅在所有最终目标接收到 NOTIFY 消息时才请求确认。此用法的一个示例是,消息被发送到一个组或分发列表,且有多个 WATCHERS 正在等待 NOTIFY 消息。
此外,在 NOTIFY 请求中,另一个标头是 RVP-Hop-Count。这是一个基于 1 的值,指定为产生此请求已经发生了多少次转发。
客户机->服务器 RVP-Hop-Count = 1
服务器->服务器 RVP-Hop-Count = 2
服务器->客户机 RVP-Hop-Count = 3
NOTIFY 方法使用新的 RVP XML 元素:message、propnotification、notification-from、notification-to、contact、description、msgbody 和 mime-data。
示例
此示例说明 PRESENTITY http://im.example.com/instmsg/aliases/deriks 如何将即时消息发送到 INSTANT INBOX http://im.acmewidgets.com/instmsg/aliases/maxb。
>>请求
NOTIFY /instmsg/aliases/maxb HTTP/1.1
Host: im.acmewidgets.com
RVP-Notifications-Version: 0.2
RVP-Ack-Type: DeepOr
RVP-Hop-Count: 1
RVP-From-Principal: http://im.example.com/instmsg/aliases/deriks
Content-Type: text/xml
Content-length: XXXX
<?xml version="1.0"?>
<D:notification xmlns:D="DAV:"
xmlns:Z="http://schemas.microsoft.com/rvp/">
<Z:message>
<Z:notification-from>
<Z:contact>
<D:href>
http://im.example.com/instmsg/aliases/deriks
</Z:href>
<Z:description>
Derik Stenerson
</Z:description>
</Z:contact>
</Z:notification-from>
<Z:notification-to>
<Z:contact>
<D:href>
http://im.acmewidgets.com/instmsg/aliases/maxb</D:href>
<Z:description>
max
</Z:description>
</Z:contact>
</Z:notification-to>
<Z:msgbody>
<Z:mime-data>
<![CDATA[MIME-Version: 1.0
Content-Type: text/plain;
charset=UTF-8
X-MMS-IM-Format:
FN=Microsoft%20Sans%20Serif; EF=;
CO=0; CS=0; PF=22
Session-Id: {79FC61B5-1234-1234-
8A10-941F33CA4C90}
Let's have lunch
]]>
</Z:mime-data>
</Z:msgbody>
</Z:message>
</Z:notification>
>>响应
HTTP/1.1 200 Successful
RVP-Notifications-Version: 0.2
此示例说明在 deriks 登录时 NOTIFY 消息是如何发送给 maxb 的。为了此示例所要达到的目的,PRINCIPAL http://im.example.com/instmsg/aliases/deriks 位于联系人列表 http://im.acmewidgets.com/users/maxb 上,并且 maxb 已经订阅了 deriks 的在线状态。
>>请求
NOTIFY / HTTP/1.1
RVP-Hop-Count: 2
RVP-Notifications-Version: 0.2
Host: 128.1.1.11
Content-Length: XXXX
Content-Type: text/xml
RVP-From-Principal: im.example.com
<?xml version="1.0"?>
<Z:notification xmlns:D="DAV:"
xmlns:Z="http://schemas.microsoft.com/rvp/">
<Z:propnotification>
<Z:notification-from>
<Z:contact>
<D:href>
http://im.example.com/instmsg/aliases/deriks
</D:href>
<Z:description/>
</Z:contact>
</Z:notification-from>
<Z:notification-to>
<Z:contact>
<D:href>
http://im.acmewidgets.com/instmsg/aliases/maxb
</D:href>
<Z:description/>
</Z:contact>
</Z:notification-to>
<D:propertyupdate>
<D:set>
<D:prop>
<Z:state>
<Z:online/>
</Z:state>
</D:prop>
</D:set>
</D:propertyupdate>
</Z:propnotification>
</Z:notification>
>>响应
HTTP/1.1 200 Successful
RVP-Notifications-Version:0.2
ACL
ACL 方法为 XML 架构提供了一些补充。访问控制列表 (ACL) 用来确定谁可以访问和更新节点上的信息。例如,它限制 WATCHER 查看 PRESENTITY 是否在线的能力。
RVP ACL 的名称空间与 WEBDAV ACL 的稍有不同,因为有几个元素是不需要的,另外又添加了几个新元素。名称空间是 http://schemas.microsoft.com/rvp/acl/。