Receive messages
This guide shows you how to receive messages and other real-time events from a PubNub channel. In an entity-capable SDK, that's three steps: create a subscription, register a handler on it, and call subscribe().
- Create a subscription from a channel, and register a handler that receives its messages.
- Register handlers for the other event types a subscription delivers.
- Subscribe to several channels at once with a subscription set.
- Receive presence events on the same subscription.
Every call on this page needs an SDK instance initialized with your subscribe key. If you don't have a keyset yet, start with Set up your account. If you already have a subscription and only need to add a handler for a different event type, skip to Register handlers for other event types.
Not every SDK supports entities yet. If yours doesn't, skip to Use the pattern for SDKs without entities.
Create a subscription and register a handler
Call .channel() on your PubNub instance to create a channel entity, then .subscription() on that entity to scope a subscription to it. Register a handler on the subscription, then call subscribe() to start receiving.
- JavaScript
- Swift
- Java
- Kotlin
- C#
- Python
1const channel = pubnub.channel('channel_1');
2const subscription = channel.subscription();
3
4subscription.onMessage = (messageEvent) => {
5 console.log('Message received:', messageEvent.message);
6};
7
8subscription.subscribe();
1let subscription = pubnub.channel("channel_1").subscription()
2
3subscription.onMessage = { message in
4 if let text = message.payload[rawValue: "text"] as? String {
5 print("Message received: \(text)")
6 }
7}
8
9subscription.subscribe()
1Channel channel = pubnub.channel("channel_1");
2Subscription subscription = channel.subscription();
3
4subscription.setOnMessage(event ->
5 System.out.println("Message received: " + event.getMessage()));
6
7subscription.subscribe();
1val channel = pubnub.channel("channel_1")
2val subscription = channel.subscription()
3
4subscription.onMessage = { event ->
5 println("Message received: ${event.message}")
6}
7
8subscription.subscribe()
1Subscription subscription = pubnub.Channel("channel_1").Subscription();
2
3subscription.onMessage += (Pubnub pn, PNMessageResult<object> messageEvent) =>
4{
5 Console.WriteLine($"Message received: {messageEvent.Message}");
6};
7
8subscription.Subscribe<object>();
1subscription = pubnub.channel('channel_1').subscription()
2
3def on_message(message):
4 print('Message received:', message.message)
5
6subscription.on_message = on_message
7
8subscription.subscribe()
Registering the handler and calling subscribe() are two separate steps, and the order between them doesn't matter as long as both happen. Nothing arrives until subscribe() runs, and a handler registered after it fires identically to one registered before. For why the model works this way, refer to A listener is a callback, not a connection.
Register handlers for other event types
A subscription delivers more than messages. Register a handler the same way for any of the other five client-side event types: signals, presence, App Context, message actions, and files.
- JavaScript
- Java
- Kotlin
- C#
- Python
1subscription.addListener({
2 message: (messageEvent) => { console.log('Message:', messageEvent); },
3 presence: (presenceEvent) => { console.log('Presence:', presenceEvent); },
4 signal: (signalEvent) => { console.log('Signal:', signalEvent); },
5 objects: (objectsEvent) => { console.log('App Context:', objectsEvent); },
6 messageAction: (messageActionEvent) => { console.log('Message action:', messageActionEvent); },
7 file: (fileEvent) => { console.log('File:', fileEvent); },
8});
1subscription.setOnMessage(event -> { /* Handle message */ });
2subscription.setOnSignal(event -> { /* Handle signal */ });
3subscription.setOnPresence(event -> { /* Handle presence, requires receivePresenceEvents */ });
4subscription.setOnMessageAction(event -> { /* Handle message action */ });
5subscription.setOnFile(event -> { /* Handle file event */ });
6subscription.setOnUuidMetadata(event -> { /* Handle App Context user metadata event */ });
7subscription.setOnChannelMetadata(event -> { /* Handle App Context channel metadata event */ });
8subscription.setOnMembership(event -> { /* Handle App Context membership event */ });
1subscription.onMessage = { message -> /* Handle message */ }
2subscription.onSignal = { signal -> /* Handle signal */ }
3subscription.onPresence = { presence -> /* Handle presence, requires receivePresenceEvents */ }
4subscription.onMessageAction = { messageAction -> /* Handle message action */ }
5subscription.onFile = { file -> /* Handle file event */ }
6subscription.onObjects = { obj -> /* Handle App Context event */ }
1subscription.onMessage += (Pubnub pn, PNMessageResult<object> e) => { /* Handle message */ };
2subscription.onPresence += (Pubnub pn, PNPresenceEventResult e) => { /* Handle presence, requires ReceivePresenceEvents */ };
3subscription.onSignal += (Pubnub pn, PNSignalResult<object> e) => { /* Handle signal */ };
4subscription.onMessageAction += (Pubnub pn, PNMessageActionEventResult e) => { /* Handle message action */ };
5subscription.onFile += (Pubnub pn, PNFileEventResult e) => { /* Handle file event */ };
6subscription.onObjects += (Pubnub pn, PNObjectEventResult e) => { /* Handle App Context event */ };
1subscription.on_message = lambda message: None # Handle message
2subscription.on_signal = lambda signal: None # Handle signal
3subscription.on_presence = lambda presence: None # Handle presence, requires receivePresenceEvents
4subscription.on_message_action = lambda action: None # Handle message action
5subscription.on_file = lambda file: None # Handle file event
Each SDK also offers a generic-listener call that registers several of these handlers in one object instead of one property at a time. Go and Objective-C predate entities and expose only one of the two styles. For that contrast per SDK, and for what a handler receives when it fires, refer to Two ways to register a handler and Client-side events.
Subscribe to several channels with a subscription set
Build a subscription set from channel names, register handlers on the set instead of on each subscription, and call subscribe() once to activate every member.
- JavaScript
- Kotlin
1const subscriptionSet = pubnub.subscriptionSet({ channels: ['chats.room1', 'chats.room2'] });
2
3subscriptionSet.onMessage = (messageEvent) => {
4 console.log('Message received:', messageEvent.message);
5};
6
7subscriptionSet.subscribe();
1val subscriptionSet = pubnub.subscriptionSetOf(channels = setOf("chats.room1", "chats.room2"))
2
3subscriptionSet.onMessage = { event ->
4 println("Message received: ${event.message}")
5}
6
7subscriptionSet.subscribe()
A handler registered on a set fires for every member's events, with no separation between them unless you branch on the channel field yourself. For the other way to build a set, from Subscription objects you already created, and for how a set's scope differs from a single subscription's, refer to Two ways to build a subscription set.
Receive presence events
Pass receivePresenceEvents: true when you create the subscription. Without it, a registered onPresence handler is never called, no matter how the subscription was built.
1const subscription = pubnub.channel('channel_1').subscription({ receivePresenceEvents: true });
This also requires the Presence add-on enabled on your keyset. For the five presence event subtypes and what each one carries, refer to Presence. For the option itself and where it can and can't be set, refer to Whether a subscription receives presence events.
Use the pattern for SDKs without entities
SDKs that predate entities have no .channel() or .subscription() call. Register every handler on the PubNub client object with addListener(), then subscribe by passing channel names directly to the client's subscribe() call. Every handler then fires for every channel that client is subscribed to, with no per-channel separation.
No JavaScript example here. Showing Objective-C:
- Objective-C
- Go
1// The listener's class must conform to the PNEventsListener protocol.
2[pubnub addListener:self];
3
4- (void)client:(PubNub *)client didReceiveMessage:(PNMessageResult *)message {
5 NSLog(@"Message received: %@", message.data.message);
6}
7
8[pubnub subscribeToChannels:@[@"channel_1"] withPresence:NO];
1listener := pubnub.NewListener()
2
3go func() {
4 for {
5 select {
6 case message := <-listener.Message:
7 fmt.Println("Message received:", message.Message)
8 }
9 }
10}()
11
12pn.AddListener(listener)
13
14pn.Subscribe().
15 Channels([]string{"channel_1"}).
show all 16 linesCheck your platform's API reference before assuming either model applies to your SDK version. For why the split exists and what it costs you, refer to Listener scope follows the subscription, not the channel name.
Related tasks
- Event listeners. The listener model, the two registration styles per SDK, and how handler scope works.
- Subscriptions and subscription sets. The object model behind a subscription, and how
subscribe()andunsubscribe()change its state. - Events. Every event type, what triggers it, and the fields its payload carries.
- Filter received messages. Narrow what reaches a client before it arrives.
- Stop receiving messages. Remove a handler and unsubscribe.
- Subscribe. Multiplexing, channel groups, wildcards, and what a client is eligible to receive.