跳到主要内容

管理订阅

客户端必须使用主题订阅(Topic subscriptions),才能从其连接的 Solace PubSub+ 事件代理上的消息 VPN 中接收直接消息。订阅是客户端在发布/订阅(pub/sub)消息领域中用来表达其对希望接收的消息的兴趣的一种消息吸引器。

主题(Topic)代表一个逻辑目标。客户端可以将消息发布到主题目标,也可以订阅主题。当事件代理有一个与消息目标匹配的主题订阅时,客户端可以接收该消息。

主题可以分层组织。因此,支持通配符的主题订阅可以为客户端吸引层次结构的一部分,而无需订阅层次结构级别的每种可能组合。有关事件代理支持的字符和语法的详细信息,请参阅主题支持与语法。

主题具有以下属性:

  • 名称 — 表示要发布和/或订阅的主题的字符串。
  • 持久性 — 即它是临时的(临时主题的作用域和生命周期与其创建的会话相同)还是非临时的(在工厂级别创建)。
  • 是否启用接收全部单一投递(DTO)标志 — 当在订阅请求中启用此标志时,它会覆盖已发布消息中启用的 DTO 标志。因此,如果消息中的主题匹配,则会将消息投递给设置了“接收全部单一投递”标志的主题的客户端,以及任何未设置此覆盖的订阅主题的客户端。

在使用 JCSMP 和 .NET API 时,为订阅创建主题的流程与为消息目标创建主题的流程相同(对于直接消息,请参阅创建主题;对于保证消息,请参阅创建主题)。

相关示例

有关如何添加主题订阅的示例,请参考 JCSMP、Java RTO、C 和 .NET API 的 DirectPubSub 示例,以及 JavaScript 和 Node.js API 的 TopicSubscriber 示例。

会话级别对订阅操作的控制

许多会话级别的控制可以影响订阅操作,包括:

  • 网络 I/O 阻塞和非阻塞模式
  • 重新连接时重新应用订阅
  • 设置订阅者优先级

网络 I/O 阻塞和非阻塞模式

Java RTO、C 和 .NET API 支持在订阅和取消订阅操作中使用非阻塞网络 I/O。此功能由订阅阻塞会话属性控制。默认情况下,使用阻塞模式。

当使用非阻塞模式时,订阅请求(在 TCP 流中发送)会受到 TCP 流量控制的影响。如果消息 API 无法立即接受发送调用,则会向应用程序返回 SOLCLIENT_WOULD_BLOCK 错误代码。当可以接受时,API 会收到后续的 SOLCLIENT_SESSION_EVENT_CAN_SEND 事件,然后可以重试发送请求。在此期间,它可以继续处理其他操作。

当使用阻塞模式时,每个发送调用的调用线程会被阻塞,直到 API 可以接受该消息。因此,应用程序会自动控制发送调用的流量,使其达到事件代理可以接受的速率。发送调用会保持阻塞状态,直到被 API 接受或阻塞写入计时器到期。

PubSub+ 消息 API使用方法
Java不适用(见下文)
Java RTOSessionHandle.PROPERTIES.BLOCKING_WRITE_TIMEOUT_MS
CSOLCLIENT_SESSION_PROP_BLOCKING_WRITE_TIMEOUT_MS
.NETSessionProperties.BlockingWriteTimeoutInMsecs
JavaScript 和 Node.js不适用(见下文)

阻塞写入计时器

  • 对于 JCSMP,所有订阅和取消订阅操作均使用阻塞模式。
  • 对于 JavaScript 和 Node.js API,所有订阅和取消订阅操作均为非阻塞,并且只有在收到 solace.SessionEventCode.SUBSCRIPTION_OK 时才视为成功。

重新连接时重新应用订阅

默认情况下,客户端连接的事件代理不会维护该客户端的订阅(即,默认情况下,订阅是非持久的)。然而,可以为会话启用重新应用订阅属性,以便 API 记住客户端添加或删除的所有订阅,并且如果会话失败,客户端的最后一个订阅集将在成功重新连接时自动重新应用到事件代理。因此,启用重新应用订阅属性实际上使客户端的订阅变得持久。

此属性不适用于端点上的订阅。端点订阅由事件代理维护(即,应用于队列的主题订阅是持久的)。如果客户端使用临时队列并断开连接超过一分钟,临时队列将从事件代理中移除,并在客户端重新连接时自动重新创建。然而,即使启用了 REAPPLY_SUBSCRIPTIONS,订阅也不会重新应用。

如果在重新应用订阅时发生错误,通道连接将被标记为已断开,客户端将根据会话配置的重新连接属性尝试重新连接(请参阅重新连接重试)。必须成功重新应用订阅才能重新建立连接。

代表其他客户端进行的主题订阅不会由该客户端连接的事件代理维护——即,它们不是持久的(请参阅代表其他客户端管理主题订阅)。此外,主题订阅不会在 API 内存中维护,因此在客户端重新连接时无法重新应用。

PubSub+ 消息 API使用方法
JCSMPJCSMPProperties.REAPPLY_SUBSCRIPTIONS
Java RTOSessionHandle.PROPERTIES.REAPPLY_SUBSCRIPTIONS
CSOLCLIENT_SESSION_PROP_REAPPLY_SUBSCRIPTIONS
.NETSessionProperties.ReapplySubscriptions
JavaScript 和 Node.jssolace.SessionProperties.reapplySubscriptions

如何启用订阅的重新应用

相关示例

有关如何在会话重新连接时重新应用订阅的示例,请参考适用于相应消息 API 的 DirectPubSub 示例。

设置订阅者优先级

为了控制哪些客户端接收单一投递(DTO)消息,客户端被分配了一个本地订阅者优先级。本地优先级是指客户端的订阅在接收直接连接到的事件代理上发布的 DTO 消息时的优先级。订阅者优先级范围从 1(最高)到 4(最低)。

当消息启用 DTO 功能发布时,具有最高订阅者优先级的本地客户端将接收该消息,如果多个客户端共享该订阅者优先级,则通过轮询方式选择一个客户端。

如果没有本地客户端具有匹配的订阅,消息可能会投递给连接到邻居事件代理的具有匹配订阅的一个客户端。

PubSub+ 消息 API使用方法
JCSMPJCSMPProperties.SUBSCRIBER_LOCAL_PRIORITY
Java RTOSessionHandle.PROPERTIES.SUBSCRIBER_LOCAL_PRIORITY
CSOLCLIENT_SESSION_PROP_SUBSCRIBER_LOCAL_PRIORITY
.NETSessionProperties.SubscriberLocalPriority
JavaScript不支持 DTO
Node.jssolace.SessionProperties.subscriberNetworkPriority

订阅者优先级

相关示例

有关如何使用 DTO 发布和订阅消息的示例,请参考适用于相应消息 API 的 DTOPubSub 示例。

添加主题订阅

在发布/订阅消息领域中,客户端可以使用主题订阅来吸引感兴趣的消息。

要向事件代理添加主题订阅,请调用适用于所使用消息 API 的方法或函数,并传入主题订阅。您还可以设置可选的订阅标志以控制 API 调用的行为。

可以设置的订阅标志包括:

  • 等待确认(适用于 JCSMP、Java RTO、C 和 .NET)
  • 请求确认(适用于 Java RTO、C、.NET、JavaScript 和 Node.js)
  • 接收全部单一投递(适用于 JCSMP、Java RTO、C 和 .NET)

仅包含“>”字符的主题订阅将吸引所有已发布的消息,无论其主题是什么,并且它作为“始终投递”订阅(即,它覆盖了已发布消息中启用的单一投递标志)。

PubSub+ 消息 API使用方法
JCSMPJCSMPSession.addSubscription(...)
Java RTOSessionHandle.subscribe(...)
CsolClient_session_topicSubscribeExt(...)
.NETISession.Subscribe(...)
JavaScript 和 Node.jssolace.Session.subscriber(...)

如何添加订阅

相关示例

有关如何添加主题订阅的示例,请参考 Java、Java RTO、C 和 .NET API 的 DirectPubSub 示例,以及 JavaScript 和 Node.js API 的 TopicSubscriber 示例。

代表其他客户端管理主题订阅

客户端可以作为订阅管理器,为同一消息 VPN 中的其他客户端添加和移除主题订阅。要成为订阅管理器,客户端必须使用已配置为订阅管理器的客户端用户名连接到路由器。这些客户端被称为 OBO(On-Behalf-Of)代理,或 OBO 订阅管理器。使用 OBO 订阅管理器可以集中管理哪些客户端获得哪些订阅。有关如何为客户端用户名启用订阅管理器功能的信息,请参阅配置订阅管理器。

  • 只有直接消息可以通过代表其他客户端进行的主题订阅接收。

  • 订阅管理器只能为客户端添加直接消息的主题订阅,它不一定有权修改这些客户端拥有的保证消息端 点(队列或主题端点)的订阅。

  • 订阅管理器必须为客户端创建一个客户端名称端点,才能为其添加或移除主题订阅。当代表其他客户端添加订阅时,它们的行为与其他订阅相同。例如,如果客户端断开连接,订阅管理器添加的订阅将被移除。断开订阅管理器的连接不会影响已添加的订阅。

JCSMP、Java RTO 和 .NET API

对于 JCSMP、Java RTO 和 .NET API,必须首先为每个要管理订阅的客户端创建一个客户端名称端点实例。创建客户端名称端点实例后,订阅管理器可以向该客户端名称端点实例添加主题订阅或从中移除主题订阅。

C API

对于 C API,当订阅管理器客户端使用以下列出的函数之一代表其他客户端添加或移除订阅时,必须传入端点类型为客户端名称端点(SOLCLIENT_ENDPOINT_PROP_CLIENT_NAME)和该端点的名称作为端点属性。

PubSub+ 消息 API使用方法
JCSMP- JCSMPFactory.createClientName(...)
  • JCSMPSession.addSubscription(...)
  • JCSMPsession.removeSubscription(...) | | Java RTO | - Solclient.Allocator.newClientName(...)
  • SessionHandle.subscribe(...)
  • SessionHandle.unsubscribe(...) | | C | - solClient_session_endpointTopicSubscribe(...)
  • solClient_session_endpointTopicUnsubscribe(...) | | .NET | - ContextFactory.CreateClientName(...)
  • ISession.Subscribe(...)
  • ISession.UnSubscribe(...) | | JavaScript 和 Node.js | 目前不支持 | | JMS | 目前不支持 |

如何代表其他客户端管理主题订阅

相关示例

有关如何使用订阅管理器客户端代表其他客户端添加主题订阅的示例,请参考:

  • C API 的 SubscribeOnBehalfOfClientExample.m
  • Java RTO API 的 SubscribeOnBehalfOfClient.java
  • JCSMP API 的 SubscribeOnBehalfOfClient.java

移除订阅

您还可以设置可选的订阅标志以控制 API 调用的行为。(这些标志与其添加订阅的对应标志相同。)

PubSub+ 消息 API使用方法
JCSMPJCSMPsession.removeSubscription(...)
Java RTOSessionHandle.unsubscribe(...)
CsolClient_session_topicUnsubscribeExt(...)
.NETISession.UnSubscribe(...)
JavaScript 和 Node.jssolace.Session.unsubscribe(...)

相关示例

有关如何移除主题订阅的示例,请参考 Java、Java RTO、C 和 .NET API 的 DirectPubSub 示例,以及 JavaScript 和 Node.js API 的 TopicSubscriber 示例。