Subscribe to a Channel
As PubNub allows you to subscribe to hundreds or even thousands of channels, it's vital to understand how to efficiently manage them. The sections on this page focus on the different ways you can subscribe to multiple channels with channel groups, wildcards, and filters. Also, refer to the Metadata page to learn how to add metadata to provide additional information about your channels and their occupants.
Subscribe to Channels
Once the listener object is established, the client can start issuing requests to subscribe to individual channels. Subscribing to channels initiates a connection with the PubNub Platform which triggers a connection status event. This connection is kept open for the duration that the client stays subscribed to at least one channel. Any user subscribing to a channel will receive messages in under 100ms, regardless of which global region the message was sent.
The client can subscribe to several channels simultaneously through a single open connection. Typically, you subscribe to channels on app load. As the user navigates through your app, your app can remain subscribed to all the channels so it continues to receive messages on all of them. Alternatively, you can implement your app in a way that it subscribes and unsubscribes from channels as the user navigates through the app.
pubnub.subscribe({channels: ["chats.room1", "alerts.system"]});
pubnub.subscribe(to: ["chats.room1", "alerts.system"])
[self.pubnub subscribeToChannels: @[@"chats.room1", @"alerts.system"] withPresence:NO];
pubnub.subscribe().channels(Arrays.asList("chats.room1", "alerts.system"));
pubnub.Subscribe<string>()
.Channels(new string[] {"chats.room1", "alerts.system"})
.Execute();
pubnub.subscribe()\
.channels("chats.room1", "alerts.system")\
.execute()
Signal Channel Subscribe
To receive Signals, you don't need a different subscription to the channel, but you do need a separate signal
event handler as mentioned in the Application Setup section.
Channel Multiplexing
Subscribing to multiple channels from a single client is called multiplexing. You can subscribe to one or more channels by providing the channel names as an array of strings. Multiplexing allows each client to subscribe to a combination of channels of their choosing and change that selection at any time.
Multiplexing is designed for a relatively small number of channels. While there is no hard limit, PubNub strongly recommends multiplexing no more than 30 channels for any subscribe, and possibly fewer if you are deploying a larger application. For bigger channel subscribe groupings, you should consider using Channel Groups.
You can subscribe to one or more channels in a single request or you can spread those requests out in your application's flow. For example, a client might subscribe to chats.room1
now and then later subscribe to chats.room2
. Doing so will simply add chats.room2
to the current list of channels that have already been subscribed as if you subscribed to them at the same time.
For example, below is how you would subscribe to a channel chats.room1
when the user of your app enter their first chat room.
pubnub.subscribe({channels: ["chats.room1"]});
pubnub.subscribe(to: ["chats.room1"])
[self.pubnub subscribeToChannels: @[@"chats.room1"] withPresence:NO];
pubnub.subscribe().channels(Arrays.asList("chats.room1"));
pubnub.Subscribe<string>()
.Channels(new string[] {"chats.room1"})
.Execute();
pubnub.subscribe()\
.channels("chats.room1")\
.execute()
The user continues to use your application, and then decides to enter another chat room, chats.room2
.
pubnub.subscribe({channels: ["chats.room2"]});
pubnub.subscribe(to: ["chats.room2"])
[self.pubnub subscribeToChannels: @[@"chats.room2"] withPresence:NO];
pubnub.subscribe().channels(Arrays.asList("chats.room2"));
pubnub.Subscribe<string>()
.Channels(new string[] {"chats.room2"})
.Execute();
pubnub.subscribe()\
.channels("chats.room2")\
.execute()
The result is that the user is now subscribed to both chat room channels.
You can also leverage Channel Groups and Wildcard Subscribe. Below you'll be briefly introduced to these two alternative subscription management features.
Channel Groups
Applications often require listening to several channels at once. Many may require hundreds or even thousands of channels. Channel Groups can also be thought of as a Subscribe Group, because you can only subscribe to a Channel Group; you can't publish to a Channel Group.
There are definite advantages to using Channel Groups when your clients must subscribe to a lot of channels. Channel Groups allow a client to subscribe to 2000 channels at once. Your server adds channels to a channel group and clients can subscribe to all those channels contained in the channel group simply by subscribing to that channel group.
You can think of a channel group like a pointer to a list of channels on your server. The end result is that the subscribe request has a single channel group in the HTTP URL rather than hundreds of individual channels.
Each individual client can subscribe to a maximum of 10 channel groups for a total of up to 20,000 channels. Your clients may not need to listen to that many channels, but Channel Groups make it possible for your server to manage the channels that the client is subscribed to by adding and removing channels on behalf of the clients.
To use a Channel Group, instead of multiplexing, there is just one additional step: add channels to a channel group.
Add channels to a channel group. This also creates the channel group if it doesn't already exist. This should be performed by your server for security and ease of management.
pubnub.channelGroups.addChannels({
channels: ["chats.room1", "chats.room2", "alerts.system"]
channelGroup: "cg_user123"
},
function(status) {
console.log(status);
}
);
pubnub.add(
channels: ["chats.room1", "chats.room2", "alerts.system"],
to: "cg_user123"
) { result in
switch result {
case let .success(response):
print("succeeded: \(response)")
case let .failure(error):
print("failed: \(error.localizedDescription)")
}
}
[self.pubnub addChannels: @[@"chats.room1", @"chats.room2", @"alerts.system"]
toGroup:"cg_user123" withCompletion:^(PNAcknowledgmentStatus *status) {
// handle success/error
}];
pubnub.addChannelsToChannelGroup()
.channelGroup("cg_user123")
.channels(Arrays.asList("chats.room1", "chats.room2", "alerts.system"))
.async(new PNCallback<PNChannelGroupsAddChannelResult>() {
@Override
public void onResponse(PNChannelGroupsAddChannelResult result, PNStatus status) {
if (status.isError()) {
System.out.println("failed: " + status.getMessage());
}
else System.out.println("succeeded");
}
});
pubnub.AddChannelsToChannelGroup()
.ChannelGroup("cg_user123")
.Channels(new string[] {"chats.room1", "chats.room2", "alerts.system"})
.Execute(new PNChannelGroupsAddChannelResultExt((result, status) => {
// handle success/error
}
));
pubnub.add_channel_to_channel_group()\
.channels(["chats.room1", "chats.room2", "alerts.system"])\
.channel_group("cg_user123")\
.sync()
The client subscribes to the channel group.
pubnub.subscribe({
channelGroups: ["cg_user123"],
withPresence: true
});
pubnub.subscribe(
to: [],
and: ["cg_user123"],
withPresence: true
)
[self.pubnub subscribeToChannelGroups:@["cg_user123"] withPresence:true];
pubnub.subscribe()
.channelGroups(Arrays.asList("cg_user123"))
.withPresence()
.execute();
pubnub.Subscribe<string>()
.ChannelGroups(new string[] {"cg_user123"})
.WithPresence()
.Execute();
pubnub.subscribe()\
.channel_groups("cg_user123")\
.with_presence()\
.execute()
When messages are published to any of the channels in this channel group, it will be received in the message handler of the client's listener. The channel group subscribes can also be enabled with withPresence
parameter to start receiving presence events for all the channels in the Channel Group. Be aware of whether this is necessary for your use case or not. You can separate channels into two channels groups: cg_presence_user123
(channels with presence tracking) and cg_user123
(channels without presence tracking). This can all be done on the client app. but when we talk about channel access security (PubNub Access Manager), it will be clear why clients should never be able to add/remove channels to/from a channel group.
Additionally, with Channel Groups your server can force a client to unsubscribe from a particular channel just by removing that channel from the channel group that the client is subscribed to.
Channel Group Names
Channel groups can be shared just like channels. For example, you may want to create a channel group called cg_sports
. Multiple clients can subscribe to this shared channel group and your server can add new channels related to sports and all the clients will automatically be subscribed to those new channels.
And there is no requirement to prefix the name with cg_
. It's only a convention that makes it easy to recognize Channel Groups. So, feel free to use a naming convention that works best for your requirements and design style.
Channel Group Names
Channel Group names have the same rules as Channel names with one exception: you can't use a period in the name. This means that wildcard features do not apply to Channel Groups.
Just because you're using Channel Groups does not mean you can't also subscribe to individual channels. Sometimes it may be convenient to subscribe to a particular channel directly while also subscribing to a separate Channel Group. You can specify channels and channel groups in the same subscribe call or make individual subscribe calls. And channel groups can be multiplexed, too.
Wildcard Subscribe
Wildcard Subscribe channelName.*
can be used to subscribe to hierarchical list of channels. It's similar to Channel Group in that you can subscribe to lots of channels with a single name declaration. For example, you specify a wildcard channel pattern like sports.*
, and your app will subscribe to all channel names that match that pattern: sports.cricket
, sports.lacrosse
. This list can be virtually infinite in number with some limitations described in the next section.
pubnub.subscribe({
channels: ["alerts.*", "chats.team1.*"],
withPresence: true
});
pubnub.subscribe(
to: ["alerts.*", "chats.team1.*"],
and: [],
withPresence: true
)
[self.pubnub subscribeToChannels: @[@"alerts.*", @"chats.team1.*"] withPresence:YES];
pubnub.subscribe()
.channels(Arrays.asList("alerts.*", "chats.team1.*")
.withPresence());
pubnub.Subscribe<string>()
.Channels(new string[] {"alerts.*", "chats.team1.*"})
.WithPresence()
.Execute();
pubnub.subscribe()\
.channels("alerts.*", "chats.team1.*")\
.with_presence()\
.execute()
Wildcard Subscribe Rules
There are some limits to what you can do with the Wildcard Subscribe. Below is a quick summary of the rules:
- You're limited to two dots (three levels). For example, you can subscribe to
a.*
ora.b.*
but nota.b.c.*
. - A wildcard pattern must always end with
.*
. In other words, the*
can't be in the middle of the pattern (a.*.c
, isn't valid). - Just like Channel Groups, you can not publish to a wildcard channel pattern.
Subscribe Filter
With the metadata information being sent with the published message, we can now leverage message filtering to omit messages that aren't important for a particular client. For example, filter out messages that the client published using its UUID.
In the following code examples, the uuid
variable is used as a placeholder variable that would hold the UUID value for the client. For your servers, this value would be pulled from a server config file. For your clients, this value is received from your server after successful login.
var pubnub = new PubNub({
publishKey: "myPublishKey",
subscribeKey: "mySubscribeKey"
uuid: uuid
})
pubnub.setFilterExpression("uuid != '" + pubnub.getUUID() + "'");
// the uuid value is received from your server
var pnconfig = PubNubConfiguration(
publishKey: "myPublishKey",
subscribeKey: "mySubscribeKey",
)
pnconfig.uuid: uuid
pnconfig.filterExpression: "uuid != \(uuid)"
var pubnub = PubNub(configuration: pnconfig)
// the uuid value is received from your server
PNConfiguration *pnconfig = [PNConfiguration configurationWithPublishKey:@"myPublishKey"
subscribeKey:@"mySubscribeKey"];
pnconfig.uuid = uuid;
self.pubnub = [PubNub clientWithConfiguration:pnconfig];
NSString *filterExp = [NSString stringWithFormat:@"uuid != '%@'",
self.pubnub.currentConfiguration.uuid];
[self.pubnub setFilterExpression:filterExp];
// the uuid value is received from your server
PNConfiguration pnconfig = new PNConfiguration();
pnconfig.setPublishKey("myPublishKey");
pnconfig.setSubscribeKey("mySubscribeKey");
pnconfig.setUuid(uuid);
pnconfig.setFilterExpression("uuid != '" + uuid +"'");
PubNub pubnub = new PubNub(pnconfig);
PNConfiguration pnconfig = new PNConfiguration();
pnconfig.PublishKey = "myPublishKey";
pnconfig.SubscribeKey = "mySubscribeKey";
pnconfig.Uuid = uuid;
pnconfig.FilterExpression = "uuid != '" + uuid + "'";
Pubnub pubnub = new Pubnub(pnconfig);
pnconfig = PNConfiguration()
pnconfig.publish_key = "myPublishKey"
pnconfig.subscribe_key = "mySubscribeKey"
pnconfig.uuid = uuid
pnconfig.filter_expression = "uuid !='" + uuid +"'"
pubnub = PubNub(pnconfig)
To learn more about the filter options, refer to the table in the Publish messages section.
Unsubscribe from Channels
Unsubscribe from a channel to stop receiving its messages. You can use this method to unsubscribe from one or more channels.
Unsubscribe from all Channels
Use this method to unsubscribe from all channels.