Subscriptions and subscription sets

Showing JavaScript examples.

In PubNub, a Subscription or SubscriptionSet is the object your code uses to control what a client receives. What a subscription addresses and how one connection carries many of them is the subscribe model. This page covers:

  • which entity each kind of subscription is built from, and what that entity scopes it to
  • what actually differs between a Subscription and a SubscriptionSet, beyond how many entities each one covers
  • why some SDKs let you skip holding either object, and what that trade-off costs
  • the two ways to build a SubscriptionSet, and how it relates to the subscriptions inside it
  • why calling subscribe() or unsubscribe() changes the object's state rather than sending a server-side registration
  • the one option you set when you create a subscription, and what it controls
  • which parts of the subscribe model are deliberately not properties of the object

One rule holds throughout. A subscription is a local object, not a server-side record. The PubNub network knows only the channels and channel groups named in the SDK's current subscribe request. It has no concept of the Subscription object your code is holding. So creating, discarding, or reassigning one has no effect until your code calls subscribe() or unsubscribe() on it.

What entity a subscription is built from​

Current SDKs build a subscription by calling .subscription() on an entity, and the entity decides what the resulting subscription is scoped to:

Entity.subscription() returns a subscription scoped toRefer to
ChannelOne channel's messages, signals, and other channel-level eventsChannels
ChannelGroupEvery channel currently in that group, as one unitChannel group
UserMetadataApp Context events for that user's own metadata and membershipsApp Context
ChannelMetadataApp Context events for that channel's own metadata and membershipsApp Context

Each entity is created from the PubNub client, and .subscription() on it returns a plain object. Constructing it does nothing on the network until you call subscribe() on the result.

SDKs that predate entities have no .subscription() call at all. Refer to SDK entities for that split, and to Listener scope follows the subscription, not the channel name for what the split means for the handlers you attach.

Whether to use a subscription or a set​

Both objects deliver the same event types through the same handlers. The difference is where a handler's boundary sits.

  • A Subscription scoped to one entity keeps that entity's events isolated from every other entity's. A handler registered on it never has to inspect the channel name to know what it's looking at, because nothing else can reach that handler.
  • A SubscriptionSet removes that isolation on purpose. One handler runs for every member's events, so logic that should behave identically across entities needs to exist only once, instead of copied onto several Subscription objects.
SubscriptionSubscriptionSet
Built fromone entityseveral entities, or several existing Subscription objects
A handler registered on it fires foronly that entity's eventsevery member's events
Calling subscribe() or unsubscribe() on itactivates or deactivates that one entityactivates or deactivates every member at once

Every event still carries the channel it arrived on, so a handler on a set can recover per-entity behavior by branching on that field. A handler on a single Subscription has no such branch to write, because nothing else ever reaches it.

Whether to let the client manage subscriptions for you​

Some SDKs also expose a client-level subscribe() that takes channel and channel group names directly paired with a client-level addListener() for handlers. This isn't a remnant from before entities existed. All three fully support the Subscription and SubscriptionSet objects described on this page, and keep the client-level call as a second, permanent way to reach the same result. Check your SDK's API reference before assuming either holds for your specific SDK version.

Choosing it trades away the granularity described in Whether to use a subscription or a set, on purpose. Every channel and channel group you name this way lands in one scope the client keeps for you. Every handler you register at the client level then fires for all of it, the same way one ever-growing SubscriptionSet would. That's the point: no entity to create first, no Subscription variable to hold onto, no set to assemble by hand. The cost is the same one a SubscriptionSet carries: you can't isolate one channel's handling from another's without branching on the event's channel field yourself inside a shared handler.

Two ways to build a subscription set​

A SubscriptionSet groups several subscriptions so that one subscribe() call, one unsubscribe() call, and one handler registration cover all of them. There are two ways to build one, and they start from opposite ends:

  • From names or entities directly. Some SDKs let you ask the client for a set in one call, without creating each member subscription yourself first, for example pubnub.subscriptionSet({ channels: ['ch1', 'ch2'] }) from channel names. A few SDKs accept a mixed list of entities the same way, so one call can build a set covering a Channel, a ChannelGroup, and a UserMetadata object together.
  • From subscriptions you already created. Combine existing Subscription objects into a set, for example by calling .addSubscription() on one and passing another. This is the path that fits an application built incrementally. One component created a subscription for its own channel earlier, and a second component now needs to fold it into a shared set.

The examples below build two entity-scoped subscriptions and combine them into one set before subscribing. Method names differ between SDKs, and not every SDK that supports entities exposes this combine operation the same way, so check your platform's API reference for the exact call.

The following JavaScript is illustrative rather than a working application:

1const subscription1 = pubnub.channel('chats.room1').subscription({ receivePresenceEvents: true });
2const subscription2 = pubnub.channel('chats.room2').subscription();
3
4// Combine two existing subscriptions into a set
5const subscriptionSet = subscription1.addSubscription(subscription2);
6
7subscriptionSet.subscribe();

A Subscription combined into a set this way keeps working on its own: both it and the set it now belongs to can be active at once, independently of each other. Refer to Listener scope follows the subscription, not the channel name for how handler scope follows this structure.

What subscribe and unsubscribe change​

subscribe() and unsubscribe() are the switch on a Subscription or SubscriptionSet, not a message sent about that specific object. Calling subscribe() adds the object's channels and channel groups to the single list the SDK's subscribe loop is currently requesting. Calling unsubscribe() removes them from that list. What the network sees is only the resulting list, never the objects that produced it.

Three consequences follow from that:

  • The object survives unsubscribe(). Unsubscribing stops events from arriving through that object, but the object itself, and every handler still registered on it, remains. Calling subscribe() on the same object again resumes it. That is what makes "pause and later resume the same scope" cheaper than discarding the object and rebuilding it from the entity.
  • A SubscriptionSet's subscribe() and unsubscribe() apply to every member at once. There is no partial subscribe of a set: activating or deactivating it activates or deactivates every subscription it currently contains.
  • unsubscribeAll() is a separate, client-wide operation. Some SDKs expose it on the PubNub client itself. It stops every subscription and subscription set that client holds in one call, regardless of how many separate objects created them. For the procedure and the calls each SDK exposes, refer to Stop receiving messages.

Whether a subscription receives presence events​

Creating a subscription or subscription set takes an options argument alongside the entity, a SubscriptionOptions object in SDKs that name the type, or a plain object in SDKs that don't. receivePresenceEvents is the one subscription option verified across SDKs today. It decides whether that object's handlers also receive the presence join, leave, and timeout events for its scope. It is not something you can add to an already-created object. Setting it happens at the same call that produces the subscription, as in pubnub.channel('chats.room1').subscription({ receivePresenceEvents: true }).

A subscribe filter is not a second subscription option, even though older documentation grouped it with receivePresenceEvents this way. Refer to What a subscription is not for where it actually lives. Refer to Receive presence events for what the resulting join, leave, and timeout events carry.

What a subscription is not​

  • Not where a subscribe filter lives. A subscribe filter expression is a property of the client, applying to every channel and channel group that client subscribes to. Creating a subscription with different intentions per channel does not give each one a different filter. That needs either a separate client instance or client-side filtering in the handler. Refer to Filter received messages.
  • Not where connection status lives. The status handler reports the shared subscribe connection, so it is registered on the PubNub client object, never on a Subscription or SubscriptionSet. Refer to The status handler is the exception.
  • Not available in every SDK. SDKs that predate entities have no Subscription or SubscriptionSet object at all. They subscribe channels and channel groups directly on the client and register every handler there. That is the only model they offer. Check your platform's API reference before assuming the object model in this page applies. Refer to SDK entities.
  • Not the only path, even where it's fully supported. Some entity-capable SDKs keep a client-level subscribe() and addListener() alongside Subscription and SubscriptionSet, as a deliberate second option. Refer to Whether to let the client manage subscriptions for you for more information.

Next steps​

Was this page useful?

Last updated on