5.3. 共享外观用户代理
支持共享外观 (shared appearances) 功能的 UA 使用带有共享外观扩展的对话状态包 [RFC4235], 以及 Section 13 中定义的 'shared' Event 头字段参数.
UA 使用 Section 5.2 中的对话包扩展, 并配合 SUBSCRIBE [RFC6665], NOTIFY [RFC6665] 和 PUBLISH [RFC3903]. 对话事件包的 SUBSCRIBE, NOTIFY 和 PUBLISH 请求按本规范要求包含 'shared' Event 头字段参数.
'shared' Event 头字段参数的存在会告知外观代理 (Appearance Agent), 该 UA 支持本规范.
初始化时, UA MUST 订阅 AOR 的对话事件包, 并按照 SIP 事件框架 (SIP Events Framework) [RFC6665] 刷新订阅. 如果 SUBSCRIBE 请求失败, 则可能不存在外观代理, 且此功能未在该 AOR 上激活. UA MAY 定期重试订阅以检查条件是否已改变, 重试间隔不得短于四小时.
选择四小时是为了将每个 UA 每天的订阅测试限制为六次. 增加此间隔会减少这种失败流量, 但也会使新激活的外观代理需要更长时间才能被发现.
UA 还可以利用 NOTIFY 中是否存在 'shared' Event 头字段参数, 来发现该 AOR 是否存在外观代理.
实现共享外观功能, 呼叫代答, 加入和桥接的 UA MUST 支持发送带有 Replaces [RFC3891] 或 Join [RFC3911] 的 INVITE. 用户代理客户端 (User Agent Client, UAC) 需要在 Replaces 或 Join 头中包含 to-tag 和 from-tag 信息, 以便用户代理服务器 (User Agent Server, UAS) 按照 RFC 3891 和 RFC 3911 中的规则匹配正确的对话.
所有实现共享外观功能并支持 INVITE 的 UA MUST 支持接收带有 Replaces [RFC3891] 或 Join [RFC3911] 头字段的 INVITE.
在发布或通知对话包信息时, UA 包含发布时可用的最大对话标识集合, 但如果 UA 希望防止其他 UA 加入或代答某个呼叫, 则可以省略信息. 对话标识包括本地和远程目标 URI, call-id, to-tag 和 from-tag. 虽然这些对话标识信息在 [RFC4235] 中是可选的, 但在共享外观功能中是必要的, 因为它们允许执行呼叫控制操作. 将呼叫置于保持状态时, 使用 "+sip.rendering=no" 特性标签在对话包通知中指示该状态. 如果改用完整的 SDP 会话描述, 会迫使端点执行大量额外解析, 不必要地使代码复杂化并引入错误.
准确呈现组内其他 UA 的 idle/active/alerting/hold 状态是共享外观功能的重要组成部分.
不需要占用特定外观编号 (或并不关心外观编号) 的 UA 只需像通常一样发送 INVITE 来发起出站呼叫.
如果该呼叫是紧急呼叫, UA MUST NOT 在发送 INVITE 前等待占用得到确认. 相反, 紧急呼叫 MUST 在不等待 PUBLISH 事务的情况下继续进行.
如果 UA 需要特定外观编号, 该 UA MUST 发送对话包 PUBLISH 请求, 并在发送 INVITE 之前等待 2xx 响应. 以下情况要求这样做:
-
用户为外呼占用特定外观编号时 (例如, 如果 UA 的用户界面使用这种隐喻, 则占用外观并进入 "off-hook" 状态).
-
用户请求某个外呼不使用外观编号时 (即在咨询呼叫期间, 在例如保持音乐 [RFC7088] 这样的 'service media' 呼叫期间, 或者针对不被视为共享外观组一部分的呼叫).
-
用户已选择加入 (或桥接) 某个现有呼叫时.
-
用户已选择替换 (或接管) 某个现有呼叫时.
注意, 当 UA 在建立对话之前占用外观时 (上表中的第 1 项和第 2 项), 并非所有对话信息都可用. 特别是, 当 UA 在知道目的地 URI 之前发布占用外观的尝试时, 可能只有极少的对话信息可用, 甚至没有任何对话信息可用. 例如, 在某些情况下, 只知道该呼叫的本地目标 URI, 而不知道任何对话信息. 如果初始 PUBLISH 中没有 From tag 和 Call-ID, 则 MUST 在这些信息可用后立即发送新的 PUBLISH.
第一次发布将使外观代理为该 UA 预留外观编号. 如果该发布不包含任何对话标识符 (例如 Call-ID 或 local-tag), 则外观代理无法将该外观编号分配给该 UA 的特定对话, 直到第二次发布携带某些对话标识符为止.
在早期对话状态期间, 此发布状态按 [RFC3903] 中的描述进行刷新, 否则外观代理可能重新分配该外观编号. 一旦对话转换到 confirmed 状态, 就不再需要刷新发布.
本规范假定外观代理除 UA 发布之外还有其他手段来获知 UA 对话状态. 在本规范中, PUBLISH 用于指示期望和意图中的外观编号操作. 一旦对话从 early 转换到 confirmed, 这个角色即告结束; 因此, 不需要刷新发布.
外观编号是与某个 AOR 相关的活动对话和待处理对话的简写标签. 使用此扩展构建的许多功能和服务都依赖于向人类用户正确呈现这些信息. 此外, 该功能的组属性意味着不同厂商和不同型号之间的呈现方式必须相似. 如果做不到这一点, 将极大降低这些协议扩展的价值和实用性. 在为此功能正确设计的用户界面中, 每个活动和待处理对话的外观编号会显式地 (即按外观编号) 或隐式地 (使用一种让用户清楚了解编号和顺序的用户界面隐喻) 呈现给用户. 每个对话的远端身份 (例如远程参与方身份) 不能有效替代外观编号. 每个外观的状态也要被呈现 (idle, active, busy, joined 等). UA 可以通过存在一个或多个包含其他 SIP 对话标识符的 <joined-dialog> 元素, 判断一组对话已加入 (桥接或混合) 在一起. 对话的外观编号可以从外观代理发送的, 包含 <appearance> 元素的对话包通知中获知, 也可以从传入 INVITE 中的 'appearance' Alert-Info 参数获知. 如果二者冲突, 以对话包通知为准.
用户可能选择了一个外观编号, 随后又放弃发起呼叫 (回到 on-hook). 在这种情况下, UA 按 [RFC3903] 中的描述, 通过使用 PUBLISH 移除事件状态来释放该外观编号. 如果未这样做, 外观代理将需要执行不必要的操作, 并且会占用本可由共享外观组中其他 UA 使用的外观编号.
UA SHOULD 仅在其可能应答传入呼叫时才向 AOR 注册. 如果 UA 主要用于监视共享外观组呼叫的状态以及代答或加入呼叫, 则该 UA SHOULD 只订阅 AOR, 而不向 AOR 注册. 如果监视 UA 注册而不只是订阅, 将产生大量不必要的网络流量.
所有已订阅的 UA 都会收到针对传入 INVITE 的 trying 状态对话包 NOTIFY.
UA MUST NOT 在 INVITE 或其他请求的 Alert-Info 头字段中插入 'appearance' 参数.
此操作仅由外观代理负责.