PubSub - iOS
PubSub is a short acronym for Publish-Subscribe mechanism. This mechanism is used to send and recieve messages from a particular topic. As the name suggests, for someone to send a message, they have to specify the topic and the message which should be published and for someone to receive a message, they should be subscribed to that topic.
Here is a visual to better understand publish-subscribe mechanism.

pubSub
In order to use PubSub in meeting, VideoSDK provides a class pubSub which allows you to subscribe to any topic and publish to any topic allowing to pass on messages and instructions during the meeting easily.
publish()
- This method is used for publishing message of specific topic.
- This method can be accessed from the
pubSubclass, which is subclass ofMeetingclass. - This method will accept following parameters as input:
topic: This will be the topic for which you are publishing a message.message: This will be the actual message to be published. It has to be inStringformat.options: This is an object ofPubSubPublishOptionswhich specifies the options for publish.PubSubPublishOptionshas 2 properties.persist:persistoffered the option of keeping the message around for the duration of the session. Whenpersistis set totrue, that message will be retained for upcoming participants and will be available in VideoSDK Session Dashboard with.CSVformat after completion of session.sendOnly: If you want to send a message to specific participants, you can pass their respectiveparticipantIdin form ofString[]. If you don't provide any IDs or pass anullvalue, the message will be sent to all participants by default. This is optional parameter.
- Swift
//Button that will send the message when tapped
@IBAction func sendMessageTapped(_ sender: Any) {
let options = ["persist" : true]
// publish message
Task {
do {
try await self.meeting?.pubsub.publish(topic: "CHAT", message: "How are you?", options: options)
} catch {
print("error while publish: \(error)")
}
}
}
subscribe()
-
This method is used to subscribe for particular topic.
-
meeting.pubsub.subscribe(topic, forListener, options?)accepts a listener and an optional options object. It isasync throws. All messages — realtime and old — are delivered exclusively through the listener callbacks; nothing is returned from the awaited call. -
This method will accept following parameters as input:
-
topic: This will be the topic to be subscribed. -
listener: This is an object ofPubSubMessageListenercontaining listener callbacks:-
onMessageReceived(message)— Called for every realtime message as soon as it is received.- Use this when: You want to handle each message individually, such as appending it to a chat, triggering a notification, or updating message-specific state.
- Don't use this when: The topic is high-throughput / large-scale (busy chats, live reactions, cursor positions). Firing once per message causes excessive re-renders and state updates — use
onBatchReceivedinstead.
-
onBatchReceived(messages)— Called with an array of realtime messages. These are the same messages delivered throughonMessageReceived, but grouped into a single batch.- Use this when: Processing messages in bulk is more efficient, such as performing a single state update or rendering a large list of messages.
-
onOldMessagesReceived(messages, info)— Called with persisted history in batches — fires once per batch until history is fully delivered. Only messages published withpersist: trueare delivered here.info.isLastistrueon the final batch.- Use this when: Loading chat history or restoring previously sent messages when a participant joins the meeting.
-
onMessageDrop(info)— Called when incoming realtime messages cannot be delivered. This can happen:- because the client cannot keep up with the incoming message rate (for example, due to a slow network or high CPU usage), causing overflow, or
- because
newMessageLimitis configured, which intentionally limits how many realtime messages are delivered every 500 ms. Any messages exceeding the configured limit within that window are discarded.
info.droppedCountcontains the number of messages that were not delivered.- Use this when: Notifying users that some realtime messages were missed, monitoring the effects of
newMessageLimit, or logging dropped messages for debugging and observability.
-
-
options: This is an object ofPubSubSubscribeOptions, which has below properties:-
oldMessageLimit(number) — how many old messages to receive. Pass0to receive none. If omitted, all old messages are delivered. Default: all.- When to use: Cap the history for large sessions where loading every persisted message would be wasteful (e.g. only the last 50 messages need to appear when a participant joins).
-
realtimeOverflow(RealtimeOverflow Enum) — behavior when your internet is slow or your device can't keep up.RealtimeOverflow.queue(default) queues remaining messages so you receive them once you catch up;RealtimeOverflow.dropdrops them instead.- When to use: Use
RealtimeOverflow.queuefor chat where every message matters. UseRealtimeOverflow.dropfor high-frequency, low-value streams (live reactions, cursor positions) where stale data is worse than missing data.
- When to use: Use
-
maxQueue(number) — maximum number of message batches to queue during overflow. Default:70. Max:200. Only valid withrealtimeOverflow: .queue.- When to use: Increase this value when you want to retain more messages and catch up after recovering from a slow network or CPU spike. Lower it if memory pressure matters more than history.
-
newMessageLimit(number) — maximum number of realtime messages to receive per 500 ms.- When to use: Set this when you want to render only a particular number of messages per second — for example, throttle a busy chat topic so the UI doesn't jank, or rate-limit a reactions topic.
-
-
If you call subscribe() again on the same topic with a different listener, the values of realtimeOverflow, maxQueue, and newMessageLimit are overridden by the latest subscribe() call. Other options (such as oldMessageLimit) are not affected.
Every message delivered to the listener contains the following fields:
id— unique identifier for the message.message— the actual message content that was sent.senderId—participantIdof the participant who sent the message.senderName—displayNameof the participant who sent the message.timestamp— the timestamp indicating when the message was published.topic— the topic the message was published to.payload— any additional data sent along with the message (optional).
- Swift
extension MeetingViewController: MeetingEventListener {
/// Meeting started
func onMeetingJoined() {
Task {
var demoOptions = PubSubSubscribeOptions()
demoOptions.oldMessageLimit = 50
demoOptions.realtimeOverflow = .queue
demoOptions.maxQueue = 70
demoOptions.newMessageLimit = 20
do {
try await meeting?.pubsub.subscribe(
topic: "CHAT",
forListener: self,
options: demoOptions
)
} catch {
print("\(topic) subscribe failed: \(error.localizedDescription)")
}
}
}
}
extension MeetingViewController: PubSubMessageListener {
// read message when it is received
func onMessageReceived(_ message: PubSubMessage) {
print("Message Received: " + message.message)
}
func onBatchReceived(_ messages: [VideoSDKRTC.PubSubMessage]) {
// Handle a batch of realtime messages together
print("Batch messages: \(messages.count)")
}
func onOldMessagesReceived(_ messages: [VideoSDKRTC.PubSubMessage], info: PubSubHistoryInfo) {
print("onOldMessagesReceived: \(messages.count) | isLast: \(info.isLast)")
}
func onMessageDrop(_ info: PubSubMessageDropInfo) {
// Called when incoming messages are dropped
print("\(info.droppedCount) message(s) dropped")
}
}
unsubscribe()
-
This method is used to unsubscribe for particular topic.
-
This method will accept two parameters as input:
topic: This will be the topic to be unsubscribed.listener: This is an object ofPubSubMessageListener, which was passed insubscribe().
- Swift
func unsubscribe() {
//unsubscribe to the topic 'CHAT' when onMeetingLeft is triggered
Task {
do {
try await self.meeting?.pubsub.unsubscribe(topic: "CHAT", forListener: self)
} catch {
print("unsubscribe failed: \(error)")
}
}
}
Errors
All PubSub methods are async throws and fail with the typed PubSubError enum, so you can switch over the specific case in a catch block. Cases that carry a String hold the underlying reason returned by the server.
publish() throws:
.meetingNotJoined— the operation was attempted before the meeting was joined (or after it left)..meetingReconnecting— the meeting is reconnecting. Retry once it reconnects..operationTimeout— the PubSub socket is disconnected or closed, so the operation cannot proceed..publishFailed(String)— the publish failed.
subscribe() throws:
.invalidOldMessageLimit(Int)—oldMessageLimitis negative. It must benilor>= 0..invalidMaxQueue(Int)—maxQueueis less than1..invalidNewMessageLimit(Int)—newMessageLimitis negative. It must be>= 0..maxQueueNotAllowedWithDrop—maxQueuewas set whilerealtimeOverflowis.drop. It is only valid with.queue..alreadySubscribed— this listener is already subscribed to the topic. Ensure that one listener is subscribed at most ones per topic —unsubscribe()first if you need to re-subscribe. If you need to listen the events at differnet places, use and create another listener and callsubscribe()with it..meetingNotJoined— the operation was attempted before the meeting was joined (or after it left)..meetingReconnecting— the meeting is reconnecting. Retry once it reconnects..operationTimeout— the PubSub socket is disconnected or closed..subscribeFailed(String)— the subscribe failed.
unsubscribe() throws:
.unsubscribeFailed— unsubscribe request failed.
Applications of usePubSub
PubSub is a very powerful mechanism which can be used to do alot of things which can make your meeting experience much more interactive. Some of the most common usecase that we have come across for the PubSub during a meeting are listed below:
Chat: You can utilise this to develop various Chat features, such as Private Chat and Group Chat. You can follow our chat integration guide here.Raise Hand: You can allow attendees to raise their hands at any time during the meeting, informing everyone else that someone has done so.Poll: You may make polls, let users respond to them, and display the results at the end of a poll.Question Answer Session: You can also design interactive functionality that is question-and-answer based.
Downloading PubSub Messages
All the messages from the PubSub which were published with persist : true and can be downloaded as an .csv file. This file will be available in the VideoSDK dashboard as well as throught the Sessions API.
API Reference
The API references for all the methods and events utilised in this guide are provided below.
Got a Question? Ask us on discord

