基于DLNA实现iOS,Android投屏:订阅事件通知

服务运行时,可能改变有些状态信息变量的值,这是需要及时地更新给控制点。因此控制点可以通过订阅操作,让服务通过发送事件消息来发布更新。

事件消息包括一个或多个状态变量以及他们的当前数值。这些消息也是采用 XML 格式,遵循通用事件通知体系 GENA 规定。

服务运行过程中,该服务的 服务描述文件SDD状态变量 <stateVariable> 发生了变化并且该变量的 <sendEvents> 属性为 yes 时,将会产生一个事件(Event)消息。如该状态变量的 <multicast> 属性为 yes ,则该服务把这个事件消息向整个网进行多播(Multicast)。如果为 no 或者不存在这个属性,则通过单播(Unicast)给订阅者发送消息。

单播事件消息的订阅及推送是遵循通用事件通知结构(General Event Notification Architecture,GENA)协议。协议中,控制点通常是个订阅者(Subscriber),它向服务提供者(通常是某个设备上的服务)发送订阅消息(SUBSCRIBE),建立订阅关系,然后可以继续更新订阅消息(Renewal),或者最后退订消息(Cancel)。另外,UPnP对GENA进行了一些扩展,如在事件消息中增加了一个key,来表示事件的顺序。

事件订阅和通知过程如下。
UPnP事件订阅流程

订阅

事件订阅说白了就是给某个服务的 订阅 URL<eventSubURL> 发送一条包含 回调 URL<Callback URL>订阅期限 <duration> 的订阅请求。

设备描述文档 DDD 中描述 AVTransport 服务的片段例,默认其 HOST: 192.168.1.243:46201

订阅请求

上述服务的订阅请求如下,其中注意点就是 回调URL CALLBACK 必须带有 <> 否则回调不成功。为了接受回调还需要手机上运行一个 HTTP Server,具体实现请看下一部分。

订阅响应

成功响应

如果订阅成功,则服务 30s 内返回如下的响应。其中 SID 为订阅标识符,必须以uuid开头。订阅成功后需要保存,后续续订和取消订阅均需要提供该标识符。此外还需要保存订阅期限 TIMEOUT: Second-3600

订阅失败

若订阅失败,发布者必须返回一个订阅失败响应。格式如下:

iOS实现

用Swift实现的订阅请求如下

续订

如果需要续订某个服务,则必须在订阅期限过期前,将续订消息发往服务器进行续订。

续订请求

取消订阅

不需要在关注特定服务的事件时,需要向服务器发送取消订阅消息。

取消订阅请求

单播事件消息

当服务器上的状态变量发生变数时,通过单播给订阅者发送通知。单播通过 HTTP 协议发送。需要在本地运行一个 HTTP Server 来接受请求。接收事件消息成功后,只需要简单返回一个 HTTP/1.1 200 OK 作为回应即刻。

坑:有些设备返回的xml中 < > 被转义,导致解析时候出错。所以需要先反转义,然后再解析。
单播消息格式如下

播放消息

忽略头部的停止播放消息

停止播放消息

忽略头部的停止播放消息

iOS实现

iOS实现我用到了一下开源库

  1. GCDWebServer – 轻量 iOS/OSX GCD的服务器框架
  2. AEXML – 轻量 XML 解析库

创建 HTTP Server

首先需要利用 GCDWebServer 创建一个 HTTP server 接受事件消息回调。具体代码如下

创建 webServer 后,可以通过 webServer.serverURL 获取 serverURL 。 这时把 "<\(webServer.serverURL)dlna/callback>" 作为回调 URL 。按照前文给出代码进行订阅就可以收到事件消息了。

解析消息

接收到通知消息后,利用 GCDWebServer 解析 XML,获取具体的动作。目前只对播放状态做了处理。

1 2 收藏 评论

关于作者:BrikerMan

简介还没来得及写 :) 个人主页 · 我的文章

相关文章

可能感兴趣的话题



直接登录
跳到底部
返回顶部