在 MQTT 协议中,并没有提供用户上、下线等行为的消息通知。于是,我们利用 MQTT 现有的一些特性,设计了 Presence。
实时在线(Presence)是云巴提供的实时获取某个频道下所有用户(别名)的上、下线通知以及订阅、取消订阅该频道的通知。
订阅了某个频道的 Presence 后,可以监听到的通知包括:
从这个定义可以看出,使用 Presence,只能监听已经设置了 别名 的客户端,未设置 别名 的客户端不会被监听。
Q: 为什么客户端必须设置别名呢?
A: 由于 Presence 消息针对的是客户端的订阅动态和在线状态,因此,消息必须有一个客户端主体。 在云巴系统内部,会为每一个连接云巴的客户端生成一个唯一的标识符,即 UID。 由于这个 UID 是一串无意义的字符串,不便于对外公开和使用,因而,我们设计了“别名”的概念来取代 UID。 用户可以通过为客户端设置不同的 “别名” 来唯一标识客户端。
请先看一个最简单的场景,初步了解 “Join/Leave/Online/Offline” 四种消息的含义:
描述
Join/Leave 通知:
Online/Offline 通知:
前文有提到,Presence 消息仅对设置了 别名 的客户端有效。
那么,客户端是否设置 别名 对 Presence 消息的收发具体有怎样的影响呢?请看下面两个例子:
描述
通过这个例子,可以看出:
订阅了 Presence 才能收到 Presence 的消息
上例中,UID 1005 虽然订阅了 Room 频道,但未订阅 Room 的 Presence,因而不会收到 Presence 消息;
Presence 消息只对设置了别名的客户端有效
上例中,UID 1003 和 1004 未设置别名,因而当他们进出房间或上下线时不会有 Presence 消息发出;
Presence 消息的订阅者本身并不要求有别名
上例中,别名为 Alex 的客户端和未设置别名的 UID 1003 或 1004 都可以收到 Presence 消息;
Presence 的实质是,对 频道 下所有用户 别名 的状态的订阅。成功订阅后,Topic 下的任何用户别名的状态一旦发生变化,都会向 Topic + '/p' 频道发送消息。
例如,某用户(客户端)通过调用 subscribe_presence("news")
来监控 news 频道下的 Presence 消息。
调用成功后,云巴系统会自动为该客户端订阅一个名为 news/p 的频道,并将 news 频道的所有的 Presence 消息发给 news/p,让用户可以实时掌控该频道所有的 Presence 消息。
注:在调用 Presence API 时,系统自动为用户订阅的 Topic + '/p' 是一个特殊的频道,不会出现在用户实际的订阅列表中。
下面以 JavaScript SDK 为例,介绍一下与频道相关的 API。
subscribe_presence
用来监听某个频道下所有用户的别名状态的变化。unsubscribe_presence
用来取消对某频道下用户别名状态变化的监听。以云巴 JavaScript SDK Demo 为例。假设频道 news 下有一个名为 defy 的用户,下线后又立刻上线;后有一个名为 cat 的用户订阅了 news 频道,之后又立刻取消订阅。如果通过 subscribe_presence
订阅了 news,就可以实时获取到 defy 和 cat 的状态变化。
打印信息如下: