For AI agents: see the complete documentation index at /llms.txt.
Event listeners
Updated
Receive event notifications.
To receive message and event notifications when you subscribe to or join channels, you add an event listener. An event listener is triggered by the SDK to inform the client about Signaling events and state changes. The listener enables you to respond to events like successful connection to Signaling, token expiration, received messages, and other presence, storage, and lock events.
Prerequisites
Ensure that you have integrated the Signaling SDK in your project and implemented the framework functionality from the SDK quickstart page.
Implement event listeners
This section shows how to use the Signaling SDK to implement event listeners.
Add event listeners
To incorporate event handling into your app, use the addEventListener method. This method allows you to add event bindings by configuring a callback
function tailored to your specific requirements:
// Handle message event
rtm.addEventListener("message", event => {
const channelType = event.channelType; // The channel type, 'STREAM' 'MESSAGE', or 'USER'
const channelName = event.channelName; // The name of the channel that this message came from
const topic = event.topicName; // (Stream channel only) The name of the topic that this message came from
const messageType = event.messageType; // The message type, 'STRING' or 'BINARY'
const customType = event.customType; // User defined type
const publisher = event.publisher; // The message publisher
const message = event.message; // The message payload
const timestamp = event.timestamp; // Event timestamp
});
// Handle presence event
rtm.addEventListener("presence", event => {
const action = event.eventType; // The event type, should be one of 'SNAPSHOT', 'INTERVAL', 'JOIN', 'LEAVE', 'TIMEOUT、'STATE_CHANGED', 'OUT_OF_SERVICE'.
const channelType = event.channelType; // The channel type, should be "STREAM", "MESSAGE" or "USER"
const channelName = event.channelName; // The name of the channel this event came from
const publisher = event.publisher; // The user who triggered this event
const states = event.stateChanged; // User state payload, only for the stateChanged event
const interval = event.interval; // Interval payload, only for the interval event
const snapshot = event.snapshot; // Snapshot payload, only for the snapshot event
const timestamp = event.timestamp; // Event timestamp
});
// Handle topic event
rtm.addEventListener("topic", event => {
const action = event.evenType; // The event type, should be one of 'SNAPSHOT', 'JOIN', 'LEAVE'.
const channelName = event.channelName; // The name of the channel this event came from
const publisher = event.userId; // The user who triggered this event
const topicInfos = event.topicInfos; // Topic information payload
const totalTopics = event.totalTopics; // The number of topics
const timestamp = event.timestamp; // Event timestamp
});
// Handle storage event
rtm.addEventListener("storage", event => {
const channelType = event.channelType; // The channel type, should be "STREAM", "MESSAGE" or "USER"
const channelName = event.channelName; // The name of the channel this event came from
const publisher = event.publisher; // The user who triggered this event
const storageType = event.storageType; // The storage type, should be 'USER' or 'CHANNEL'
const action = event.eventType; // The event type, should be one of 'SNAPSHOT', 'SET', 'REMOVE', 'UPDATE', or 'NONE'
const data = event.data; // 'USER_METADATA' or 'CHANNEL_METADATA' payload
const timestamp = event.timestamp; // Event timestamp
});
// Handle lock event
rtm.addEventListener("lock", event => {
const channelType = event.channelType; // The channel type, should be "STREAM", "MESSAGE" or "USER"
const channelName = event.channelName; // The name of the channel this event came from
const publisher = event.publisher; // The user who triggered this event
const action = event.evenType; // The event type, should be one of 'SET', 'REMOVED', 'ACQUIRED', 'RELEASED', 'EXPIRED', 'SNAPSHOT'
const lockName = event.lockName; // The name of the lock it affects
const ttl = event.ttl; // The ttl of this lock
const snapshot = event.snapshot; // Snapshot payload
const owner = event.owner; // The owner of this lock
const timestamp = event.timestamp; // Event timestamp
});
// Handle connection state change event
rtm.addEventListener("status", event => {
const currentState = event.state; // Current connection state
const changeReason = event.reason; // Why the event was triggered
const timestamp = event.timestamp; // Event timestamp
});
// Handle link state change event
rtm.addEventListener('linkState', event => {
const currentState = event.currentState;
const previousState = event.previousState;
const serviceType = event.serviceType;
const operation = event.operation;
const reason = event.reason;
const affectedChannels = event.affectedChannels;
const timestamp = event.timestamp;
const isResumed = event.isResumed;
});
// Handle token privilege will expire event
rtm.addEventListener("tokenPrivilegeWillExpire", (channelName) => {
const channelName = channelName; // The channel for which the token will expire
});Remove event listeners
To avoid performance degradation caused by memory leaks, errors, and null pointer exceptions, best practice is to unregister the event handler when you no longer need to use it.
const messageReceived = (event) => {
const channelType = event.channelType; // The channel type, should be 'STREAM' or 'MESSAGE'
const channelName = event.channelName; // The name of the channel this event came from
const topic = event.topicName; // The message topic, valid when the channelType is "STREAM".
const messageType = event.messageType; // The message type, should be "STRING" or "BINARY" .
const customType = event.customType; // User defined type
const publisher = event.publisher; // Message publisher
const message = event.message; // Message payload
const timestamp = event.timestamp; // Event timestamp
// Your business processing logic program
};
// Add Event Listener
rtm.addEventListener("message", messageReceived);
// Remove Event Listener
rtm.removeEventListener("message", messageReceived);Signaling events
Signaling offers the following events:
| Event Listener | Description |
|---|---|
message | Receive message notifications from all the message channels you have subscribed to, or topic message notifications subscribed to from all the stream channels you have joined. |
presence | Receive online status event notifications from remote users in all the message channels you have subscribed to and stream channels you have joined. The event payload data includes channel name, channel type, event type, event sender, user temporary status data, and other information. |
topic | Receive notifications of topic change events in all the stream channels you have joined. The event payload data includes information such as channel name, event type, topic name, and event sender. |
storage | Receive all channel metadata event notifications in the message channels you have subscribed to and stream channels you have joined, as well as user metadata event notifications from all subscribed users. |
lock | Receive all lock event notifications in the message channels you have subscribed to and stream channels you have joined. The event payload data contains information such as channel name, channel type, event type, and lock details. |
status | Receive event notifications for client network connection status changes. This includes channel name, connection status, reason for change, and other information. |
linkState | Receive notifications about changes in the client's network connection status, including information on the state before and after the change, service type, operation type, reason for the change, and channel list. |
tokenPrivilegeWillExpire | Receive notifications when the client token is about to expire. |
For details on the parameters passed in by each event, refer to Event listeners in the API reference.
To receive message and event notifications when you subscribe to or join channels, you add an event listener. An event listener is triggered by the SDK to inform the client about Signaling events and state changes. The listener enables you to respond to events like successful connection to Signaling, token expiration, received messages, and other presence, storage, and lock events.
Prerequisites
Ensure that you have integrated the Signaling SDK in your project and implemented the framework functionality from the SDK quickstart page.
Implement event listeners
This section shows how to use the Signaling SDK to implement event listeners.
Add an event listener
Signaling uses an RtmEventListener instance to process messages and event notifications. Each message and event notification has a corresponding event handler, where you implement your own processing logic. Refer to the following code to create and use an instance of RtmEventListener:
// Create an RtmEventListener instance
RtmEventListener eventListener = new RtmEventListener() {
@Override
public void onMessageEvent(MessageEvent event) {
// Triggered when messages are received from remote users
}
@Override
public void onPresenceEvent(PresenceEvent event) {
// Triggered when the presence info changes
}
@Override
public void onTopicEvent(TopicEvent event) {
}
@Override
public void onLockEvent(LockEvent event) {
// Triggered when the channel lock info changes
}
@Override
public void onStorageEvent(StorageEvent event) {
// Triggered when the subscribed storage info changes
}
@Override
public void onConnectionStateChange(String channelName, RtmConstants.RtmConnectionState state,
RtmConstants.RtmConnectionChangeReason reason) {
// Triggered when the connection state changes
}
@Override
public void onLinkStateEvent(LinkStateEvent event) {
// Triggered when the link state changes
}
@Override
public void onTokenPrivilegeWillExpire(String channelName) {
// Triggered when the token is about to expire
}
};
// Configure RtmClient
RtmConfig rtmConfig = new RtmConfig();
// Specify the event listener in the client configuration
rtmConfig.eventListener = eventListener;
// Create an RtmClient instance
RtmClient mRtmClient = RtmClient.create(rtmConfig);// Create an RtmEventListener instance
val eventListener = object : RtmEventListener {
override fun onMessageEvent(event: MessageEvent) {
// Triggered when messages are received from remote users
}
override fun onPresenceEvent(event: PresenceEvent) {
// Triggered when the presence info changes
}
override fun onTopicEvent(event: TopicEvent) {
}
override fun onLockEvent(event: LockEvent) {
// Triggered when the channel lock info changes
}
override fun onStorageEvent(event: StorageEvent) {
// Triggered when the subscribed storage info changes
}
override fun onConnectionStateChange(
channelName: String,
state: RtmConstants.RtmConnectionState,
reason: RtmConstants.RtmConnectionChangeReason
) {
// Triggered when the connection state changes
}
override fun onLinkStateEvent(event: LinkStateEvent) {
// Triggered when the link state changes
}
override fun onTokenPrivilegeWillExpire(channelName: String) {
// Triggered when the token is about to expire
}
}
// Configure RtmClient
val rtmConfig = RtmConfig().apply {
eventListener = this@eventListener
}
// Create an RtmClient instance
val mRtmClient = RtmClient.create(rtmConfig)Remove event listeners
To avoid performance degradation caused by memory leaks, errors, and exceptions, best practice is to unregister an event handler when you no longer need to use it.
mRtmClient.removeEventListener(eventListener);mRtmClient.removeEventListener(eventListener)The RtmClient automatically destroys event listeners when you call release.
Signaling events
Signaling SDK offers the following events:
| Event Listener | Description |
|---|---|
onMessageEvent | Receive message notifications from all the message channels you have subscribed to, or topic message notifications subscribed to from all the stream channels you have joined. The event payload data includes channel name, channel type, topic name, event sender, message payload data type, and other information. |
onPresenceEvent | Receive online status event notifications from remote users in all message channels you have subscribed to and stream channels you have joined. The event payload data includes channel name, channel type, event type, event sender, user temporary status data, and other information. |
onTopicEvent | Receive notifications of topic change events in all the stream channels you have joined. The event payload data includes information such as channel name, event type, topic name, and event sender. |
onStorageEvent | Receive all channel metadata event notifications in all message channels you have subscribed to and stream channels you have joined, as well as user metadata event notifications from all subscribed users. The event payload data includes information such as channel name, channel type, event type, and specific metadata. |
onLockEvent | Receive all lock event notifications in the message channel you have subscribed to and stream channel you have joined. The event payload data contains information such as channel name, channel type, event type, and lock details. |
onLinkStateEvent | Receive event notifications for client network connection status changes, including the connection status before and after the change, service type, operation type that caused the change, reason for the change, channel list, and other information. |
onTokenPrivilegeWillExpire | Receive event notifications that the client token is about to expire. |
onConnectionStateChanged | (Deprecated) Receive event notifications of client network connection status changes, including channel name, connection status, and reason for change. |
For details on the parameters passed in by each event, refer to Event listeners in the API reference.
To receive message and event notifications when you subscribe to or join channels, you add an event listener. An event listener is triggered by the SDK to inform the client about Signaling events and state changes. The listener enables you to respond to events like successful connection to Signaling, token expiration, received messages, and other presence, storage, and lock events.
Prerequisites
Ensure that you have integrated the Signaling SDK in your project and implemented the framework functionality from the SDK quickstart page.
Implement event listeners
This section shows how to use the Signaling SDK to implement event listeners.
Add an event listener
Signaling uses RtmListener to process messages and event notifications. Each message and event notification has a corresponding event handler, where you implement your own processing logic. Refer to the following code to create and use an instance of RtmListener:
class RtmListener: NSObject, AgoraRtmClientDelegate {
func rtmKit(_ rtmKit: AgoraRtmClientKit, didReceiveLinkStateEvent event: AgoraRtmLinkStateEvent) {
// code
}
func rtmKit(_ rtmKit: AgoraRtmClientKit, didReceiveMessageEvent event: AgoraRtmMessageEvent) {
// code
}
func rtmKit(_ rtmKit: AgoraRtmClientKit, didReceiveLockEvent event: AgoraRtmLockEvent) {
// code
}
func rtmKit(_ rtmKit: AgoraRtmClientKit, didReceiveTopicEvent event: AgoraRtmTopicEvent) {
// code
}
func rtmKit(_ rtmKit: AgoraRtmClientKit, didReceiveStorageEvent event: AgoraRtmStorageEvent) {
// code
}
func rtmKit(_ rtmKit: AgoraRtmClientKit, tokenPrivilegeWillExpire channel: String?) {
// code
}
}
do {
let config = AgoraRtmClientConfig(appId: "yourAppId", userId: "uniqueUserId")
let listener = RtmListener()
// Initializing the RTM client
let rtmClient = try AgoraRtmClientKit(config, delegate: listener)
if rtmClient != nil {
print("RTM Client initialized successfully!")
}
} catch let error {
print("Failed to initialize RTM client. Error: \\(error)")
}// Define the Event Listener
@interface RtmListener : NSObject <AgoraRtmClientDelegate>
@end
@implementation RtmListener
// Triggered when messages are received from remote users
- (void)rtmKit:(AgoraRtmClientKit *)rtmKit didReceiveMessageEvent:(AgoraRtmMessageEvent *)event {
NSString* channel = event.channelName;
AgoraRtmChannelType channel_type = event.channelType;
if (channel_type == AgoraRtmChannelTypeStream) {
NSString* topic = event.channelTopic; // if message from stream channel, user can get topic name
}
if (event.message.rawData != nil) {
NSData* message =event.message.rawData; // get binary message
} else {
NSString* message = event.message.stringData; // get string message
}
NSString* publisher = event.publisher;
}
// Triggered when the channel lock info changes
- (void)rtmKit:(AgoraRtmClientKit *)rtmKit didReceiveLockEvent:(AgoraRtmLockEvent *)event {
NSString* channel = event.channelName;
AgoraRtmChannelType channel_type = event.channelType;
AgoraRtmLockEventType event_type = event.eventType;
if (event.lockDetailList != nil) {
NSArray<AgoraRtmLockDetail *> *lock_details = event.lockDetailList; //get detail lock info
}
}
// Triggered when the presence info changes
- (void)rtmKit:(AgoraRtmClientKit *)rtmKit didReceivePresenceEvent:(AgoraRtmPresenceEvent *)event {
NSString* channel = event.channelName;
AgoraRtmChannelType channel_type = event.channelType;
AgoraRtmPresenceEventType event_type = event.type;
NSString* publisher = event.publisher;
if (event_type == AgoraRtmPresenceEventTypeInterval) {
AgoraRtmPresenceIntervalInfo* interval = event.interval;
}else if (event_type == AgoraRtmPresenceEventTypeSnapshot) {
NSArray<AgoraRtmUserState *> * snapshot = event.snapshot;
} else {
NSArray<AgoraRtmStateItem *> *states = event.states;
}
}
// Triggered when the subscribed storage info changes
-(void)rtmKit:(AgoraRtmClientKit *)rtmKit didReceiveStorageEvent:(AgoraRtmStorageEvent *)event {
AgoraRtmStorageType storage_type = event.storageType;
if (storage_type == AgoraRtmStorageTypeChannel) {
NSString* channel = event.target;
AgoraRtmChannelType channel_type = event.channelType;
} else {
NSString* user = event.target;
}
AgoraRtmMetadata* data = event.data;
}
// Triggered when the token is about to expire
- (void)rtmKit:(AgoraRtmClientKit *)rtmKit tokenPrivilegeWillExpire:(NSString *)channel {
if (channel != nil) {
// Renew specific stream channel token
} else {
// Renew rtm client token
}
}
// Triggered when the connection state changes
- (void)rtmKit:(AgoraRtmClientKit *)kit channel:(NSString *)channelName connectionChangedToState:(AgoraRtmClientConnectionState)state reason:(AgoraRtmClientConnectionChangeReason)reason {
if (channelName != nil) {
NSLog(@"stream channel connection changed now state is %d change reason is %d",state, reason);
} else {
NSLog(@"rtm client connection changed now state is %d change reason is %d",state, reason);
}
}
// Triggered when the link state changes
- (void)rtmKit:(AgoraRtmClientKit *)rtmKit didReceiveLinkStateEvent:(AgoraRtmLinkStateEvent *)event {
if (event.serviceType == AgoraRtmServiceTypeStream) {
// receive stream channel link event
} else {
// receive message link event
}
}
@end
AgoraRtmClientConfig* rtm_cfg = [[AgoraRtmClientConfig alloc] initWithAppId:@"your_appid" userId:@"your_userid"];
// Add the event listener
RtmListener* handler = [[RtmListener alloc] init];
NSError* initError = nil;
AgoraRtmClientKit* rtm = [[AgoraRtmClientKit alloc] initWithConfig:rtm_cfg delegate:handler error:&initError];After a user successfully joins a topic, the SDK triggers an didReceiveTopicEvent of type AgoraRtmTopicEventTypeRemoteJoinTopic. All users in the channel, who have enabled listening to topic events, receive this event notification.
Remove event listeners
To avoid performance degradation caused by memory leaks, errors, and exceptions, best practice is to unregister an event handler when you no longer need to use it. For example, if you don't want to use the didReceiveLockEvent event, delete the definition of the function.
Signaling events
Signaling offers the following notification callbacks:
| Event Listener | Description |
|---|---|
didReceiveMessageEvent | Receive message notifications from all the message channels you have subscribed to, or topic message notifications subscribed to from all the stream channels you have joined. The event payload data includes channel name, channel type, topic name, event sender, message payload data type, and other information. |
didReceivePresenceEvent | Receive online status event notifications from remote users in all the message channels you have subscribed to and stream channels you have joined. The event payload data includes channel name, channel type, event type, event sender, user temporary status data, and other information. |
didReceiveTopicEvent | Receive notifications of topic change events in all the stream channels you have joined. The event payload data includes information such as channel name, event type, topic name, and event sender. |
didReceiveStorageEvent | Receive all channel metadata event notifications in all message channels you have subscribed to and stream channels you have joined, as well as user metadata event notifications from all subscribed users. The event payload data includes information such as channel name, channel type, event type, and specific metadata. |
didReceiveLockEvent | Receive all lock event notifications in all the message channels you have subscribed to and stream channels you have joined. The event payload data contains information such as channel name, channel type, event type, and lock details. |
didReceiveLinkStateEvent | Receive event notifications for client network connection status changes, including the connection status before and after the change, service type, operation type that caused the change, reason for the change, channel list, and other information. |
tokenPrivilegeWillExpire | Receive event notifications that the client token is about to expire. |
For details on the parameters passed in by each event, refer to Event listeners in the API reference.
To receive message and event notifications when you subscribe to or join channels, you add an event listener. An event listener is triggered by the SDK to inform the client about Signaling events and state changes. The listener enables you to respond to events like successful connection to Signaling, token expiration, received messages, and other presence, storage, and lock events.
Prerequisites
Ensure that you have integrated the Signaling SDK in your project and implemented the framework functionality from the SDK quickstart page.
Implement event listeners
This section shows how to use the Signaling SDK to implement event listeners.
Add an event listener
Signaling uses RtmListener to process messages and event notifications. Each message and event notification has a corresponding event handler, where you implement your own processing logic. Refer to the following code to create and use an instance of RtmListener:
class RtmListener: NSObject, AgoraRtmClientDelegate {
func rtmKit(_ rtmKit: AgoraRtmClientKit, didReceiveLinkStateEvent event: AgoraRtmLinkStateEvent) {
// code
}
func rtmKit(_ rtmKit: AgoraRtmClientKit, didReceiveMessageEvent event: AgoraRtmMessageEvent) {
// code
}
func rtmKit(_ rtmKit: AgoraRtmClientKit, didReceiveLockEvent event: AgoraRtmLockEvent) {
// code
}
func rtmKit(_ rtmKit: AgoraRtmClientKit, didReceiveTopicEvent event: AgoraRtmTopicEvent) {
// code
}
func rtmKit(_ rtmKit: AgoraRtmClientKit, didReceiveStorageEvent event: AgoraRtmStorageEvent) {
// code
}
func rtmKit(_ rtmKit: AgoraRtmClientKit, tokenPrivilegeWillExpire channel: String?) {
// code
}
}
do {
let config = AgoraRtmClientConfig(appId: "yourAppId", userId: "uniqueUserId")
let listener = RtmListener()
// Initializing the RTM client
let rtmClient = try AgoraRtmClientKit(config, delegate: listener)
if rtmClient != nil {
print("RTM Client initialized successfully!")
}
} catch let error {
print("Failed to initialize RTM client. Error: \\(error)")
}// Define the Event Listener
@interface RtmListener : NSObject <AgoraRtmClientDelegate>
@end
@implementation RtmListener
// Triggered when messages are received from remote users
- (void)rtmKit:(AgoraRtmClientKit *)rtmKit didReceiveMessageEvent:(AgoraRtmMessageEvent *)event {
NSString* channel = event.channelName;
AgoraRtmChannelType channel_type = event.channelType;
if (channel_type == AgoraRtmChannelTypeStream) {
NSString* topic = event.channelTopic; // if message from stream channel, user can get topic name
}
if (event.message.rawData != nil) {
NSData* message =event.message.rawData; // get binary message
} else {
NSString* message = event.message.stringData; // get string message
}
NSString* publisher = event.publisher;
}
// Triggered when the channel lock info changes
- (void)rtmKit:(AgoraRtmClientKit *)rtmKit didReceiveLockEvent:(AgoraRtmLockEvent *)event {
NSString* channel = event.channelName;
AgoraRtmChannelType channel_type = event.channelType;
AgoraRtmLockEventType event_type = event.eventType;
if (event.lockDetailList != nil) {
NSArray<AgoraRtmLockDetail *> *lock_details = event.lockDetailList; //get detail lock info
}
}
// Triggered when the presence info changes
- (void)rtmKit:(AgoraRtmClientKit *)rtmKit didReceivePresenceEvent:(AgoraRtmPresenceEvent *)event {
NSString* channel = event.channelName;
AgoraRtmChannelType channel_type = event.channelType;
AgoraRtmPresenceEventType event_type = event.type;
NSString* publisher = event.publisher;
if (event_type == AgoraRtmPresenceEventTypeInterval) {
AgoraRtmPresenceIntervalInfo* interval = event.interval;
}else if (event_type == AgoraRtmPresenceEventTypeSnapshot) {
NSArray<AgoraRtmUserState *> * snapshot = event.snapshot;
} else {
NSArray<AgoraRtmStateItem *> *states = event.states;
}
}
// Triggered when the subscribed storage info changes
-(void)rtmKit:(AgoraRtmClientKit *)rtmKit didReceiveStorageEvent:(AgoraRtmStorageEvent *)event {
AgoraRtmStorageType storage_type = event.storageType;
if (storage_type == AgoraRtmStorageTypeChannel) {
NSString* channel = event.target;
AgoraRtmChannelType channel_type = event.channelType;
} else {
NSString* user = event.target;
}
AgoraRtmMetadata* data = event.data;
}
// Triggered when the token is about to expire
- (void)rtmKit:(AgoraRtmClientKit *)rtmKit tokenPrivilegeWillExpire:(NSString *)channel {
if (channel != nil) {
// Renew specific stream channel token
} else {
// Renew rtm client token
}
}
// Triggered when the connection state changes
- (void)rtmKit:(AgoraRtmClientKit *)kit channel:(NSString *)channelName connectionChangedToState:(AgoraRtmClientConnectionState)state reason:(AgoraRtmClientConnectionChangeReason)reason {
if (channelName != nil) {
NSLog(@"stream channel connection changed now state is %d change reason is %d",state, reason);
} else {
NSLog(@"rtm client connection changed now state is %d change reason is %d",state, reason);
}
}
// Triggered when the link state changes
- (void)rtmKit:(AgoraRtmClientKit *)rtmKit didReceiveLinkStateEvent:(AgoraRtmLinkStateEvent *)event {
if (event.serviceType == AgoraRtmServiceTypeStream) {
// receive stream channel link event
} else {
// receive message link event
}
}
@end
AgoraRtmClientConfig* rtm_cfg = [[AgoraRtmClientConfig alloc] initWithAppId:@"your_appid" userId:@"your_userid"];
// Add the event listener
RtmListener* handler = [[RtmListener alloc] init];
NSError* initError = nil;
AgoraRtmClientKit* rtm = [[AgoraRtmClientKit alloc] initWithConfig:rtm_cfg delegate:handler error:&initError];After a user successfully joins a topic, the SDK triggers an didReceiveTopicEvent of type AgoraRtmTopicEventTypeRemoteJoinTopic. All users in the channel, who have enabled listening to topic events, receive this event notification.
Remove event listeners
To avoid performance degradation caused by memory leaks, errors, and exceptions, best practice is to unregister an event handler when you no longer need to use it. For example, if you don't want to use the didReceiveLockEvent event, delete the definition of the function.
Signaling events
Signaling offers the following notification callbacks:
| Event Listener | Description |
|---|---|
didReceiveMessageEvent | Receive message notifications from all the message channels you have subscribed to, or topic message notifications subscribed to from all the stream channels you have joined. The event payload data includes channel name, channel type, topic name, event sender, message payload data type, and other information. |
didReceivePresenceEvent | Receive online status event notifications from remote users in all the message channels you have subscribed to and stream channels you have joined. The event payload data includes channel name, channel type, event type, event sender, user temporary status data, and other information. |
didReceiveTopicEvent | Receive notifications of topic change events in all the stream channels you have joined. The event payload data includes information such as channel name, event type, topic name, and event sender. |
didReceiveStorageEvent | Receive all channel metadata event notifications in all message channels you have subscribed to and stream channels you have joined, as well as user metadata event notifications from all subscribed users. The event payload data includes information such as channel name, channel type, event type, and specific metadata. |
didReceiveLockEvent | Receive all lock event notifications in all the message channels you have subscribed to and stream channels you have joined. The event payload data contains information such as channel name, channel type, event type, and lock details. |
didReceiveLinkStateEvent | Receive event notifications for client network connection status changes, including the connection status before and after the change, service type, operation type that caused the change, reason for the change, channel list, and other information. |
tokenPrivilegeWillExpire | Receive event notifications that the client token is about to expire. |
For details on the parameters passed in by each event, refer to Event listeners in the API reference.
To receive message and event notifications when you subscribe to or join channels, you add an event listener. An event listener is triggered by the SDK to inform the client about Signaling events and state changes. The listener enables you to respond to events like successful connection to Signaling, token expiration, received messages, and other presence, storage, and lock events.
Prerequisites
Ensure that you have integrated the Signaling SDK in your project and implemented the framework functionality from the SDK quickstart page.
Implement event listeners
This section shows how to use the Signaling SDK to implement event listeners.
Add an event listener
Signaling uses an RtmEventListener instance to process messages and event notifications. Each message and event notification has a corresponding event handler, where you implement your own processing logic. Refer to the following code to create and use an instance of RtmEventListener:
rtmClient.addListener(
// Handle message event
message: (MessageEvent event) {
const channelType = event.channelType; // The channel type, 'STREAM' 'MESSAGE', or 'USER'
const channelName = event.channelName; // The name of the channel that this message came from
const topicName = event.channelTopic; // (Stream channel only) The name of the topic that this message came from
const messageType = event.messageType; // The message type, 'STRING' or 'BINARY'
const customType = event.customType; // User defined type
const publisher = event.publisher; // The message publisher
const message = event.message; // The message payload
const timestamp = event.timestamp; // Event timestamp
},
// Handle presence event
presence: (PresenceEvent event) {
const action = event.type; // The event type, should be one of 'SNAPSHOT', 'INTERVAL', 'JOIN', 'LEAVE', 'TIMEOUT、'STATE_CHANGED', 'OUT_OF_SERVICE'.
const channelType = event.channelType; // The channel type, should be "STREAM", "MESSAGE" or "USER"
const channelName = event.channelName; // The name of the channel this event came from
const publisher = event.publisher; // The user who triggered this even
const states = event.stateItems; // User state payload, only for the stateChanged event
const interval = event.interval; // Interval payload, only for the interval event
const snapshot = event.snapshot; // Snapshot payload, only for the snapshot event
const timestamp = event.timestamp; // Event timestamp
},
// Handle topic event
topic: (TopicEvent event) {
const action = event.type; // The event type, should be one of 'SNAPSHOT', 'JOIN', 'LEAVE'
const channelName = event.channelName; // The name of the channel this event came from
const publisher = event.publisher; // The user who triggered this even
const topicInfos = event.topicInfos; // Topic information payload
const timestamp = event.timestamp; // Event timestamp
},
// Handle storage event
storage: (StorageEvent event) {
const channelType = event.channelType; // The channel type, should be "STREAM", "MESSAGE" or "USER"
const target = event.target; // Which channel or user triggered this event
const storageType = event.storageType; // The storage type, should be 'USER'、'CHANNEL'
const action = event.eventType; // The event type, should be one of "SNAPSHOT"、"SET"、"REMOVE"、"UPDATE" or "NONE"
const data = event.data; // USER_METADATA or CHANNEL_METADATA payload
const timestamp = event.timestamp; // Event timestamp
},
// Handle lock event
lock: (LockEvent event) {
const channelType = event.channelType; // The channel type, should be "STREAM", "MESSAGE" or "USER"
const channelName = event.channelName; // The name of the channel this event came from
const action = event.evenType; // The action type, should be one of 'SET'、'REMOVED'、'ACQUIRED'、'RELEASED'、'EXPIRED'、'SNAPSHOT'
const lockDetailList = event.lockDetailList; // Lock event payload
const timestamp = event.timestamp; // Event timestamp
},
// Handle link state event
linkState: (LinkStateEvent event) {
const currentState = event.currentState; // The current link state
const previousState = event.previousState; // The previous link state
const serviceType = event.serviceType; // The service type, Should be "stream" or "message".
const operation = event.operation; // Which operation triggered this state changed
const reason = event.reason; // The reason for this state change
const affectedChannels = event.affectedChannels; // Which channels are affected
const unrestoredChannels = event.unrestoredChannels; // Which channels are unrestored
const isResumed = event.isResumed;
const timestamp = event.timestamp; // Event timestamp
},
// Handle token event
token : (TokenEvent event) {
const channelName = event.channelName; // The channel for which the token will expire
});The message field in MessageEvent is of type Uint8List. When you receive a string message, use the utf8.decode() method from the dart:convert library to convert it to a String.
// Convert message from Uint8List to a String
String message = utf8.decode(event.message!);Remove event listeners
To avoid performance degradation caused by memory leaks, errors, and null pointer exceptions, best practice is to unregister an event handler when you no longer need to use it. To be able to unregister an event listener, avoid using anonymous functions when adding event listeners. The following code shows how to add and remove event listeners:
// Define a message event handling function
void onMessageReceived(MessageEvent event) {
print('Received message event: $event');
}
// Register the message event listener
rtmClient.addListener(
message: onMessageReceived
);
// Remove the message event listener
rtmClient.removeListener(
message: onMessageReceived
);Signaling events
Signaling SDK offers the following events:
| Event Listener | Description |
|---|---|
message | Receive message notifications from all the message channels you have subscribed to, or topic message notifications subscribed to from all the stream channels you have joined. The event payload data includes information such as channel name, channel type, topic name, event sender, and message payload data type. |
presence | Receive online status event notifications of remote users in all message channels you have subscribed to and stream channels you have joined. The event payload data includes channel name, channel type, event type, event sender, user temporary status data, and other information. |
topic | Receive notifications of topic change events in all the stream channels you have joined. The event payload data includes information such as channel name, event type, topic name, and event sender. |
storage | Receive all channel metadata event notifications in all message channels you have subscribed to and stream channels you have joined, as well as user metadata event notifications from all subscribed users. The event payload data includes information such as channel name, channel type, event type, and specific metadata. |
lock | Receive all lock event notifications in the message channel you have subscribed to and stream channel you have joined. The event payload data contains information such as channel name, channel type, event type, and lock details. |
linkState | Receive event notifications for client network connection status changes, including the connection status before and after the change, service type, operation type that caused the change, reason for the change, channel list, and other information. |
token | Receive event notifications when the client token is about to expire. |
For details on the parameters passed in by each event, refer to Event listeners in the API reference.
To receive message and event notifications when you subscribe to or join channels, you add an event listener. An event listener is triggered by the SDK to inform the client about Signaling events and state changes. The listener enables you to respond to events like successful connection to Signaling, token expiration, received messages, and other presence, storage, and lock events.
Prerequisites
Ensure that you have integrated the Signaling SDK in your project and implemented the framework functionality from the SDK quickstart page.
Implement event listeners
This section shows how to use the Signaling SDK to implement event listeners.
Add an event listener
Signaling provides the useRtmEvent hook to process messages and event notifications. Each message and event notification has a corresponding event handler, where you implement your own processing logic. Refer to the following code to implement listeners in your app:
// Listen to messages received via Signaling channel
useRtmEvent(engine, 'message', (evt) => {
const msg = new MessageEvent(evt);
console.log('[You] received a message:', msg.message, 'from:', msg.publisher);
});
// Listen to Signaling link state changes
useRtmEvent(engine, 'linkState', (eventData) => {
console.log('Link state changed:', eventData.currentState, 'reason:', eventData.reason);
if (eventData.currentState === RtmLinkState.connected) {
console.log('✅ Connected to Signaling');
} else if (eventData.currentState === RtmLinkState.failed) {
console.log('❌ Connection failed:', eventData.reason);
}
});
// Listen to presence events such as user join, leave, or state change
useRtmEvent(engine, 'presence', (presenceData) => {
console.log('[Signaling] Presence event:', presenceData.eventType);
console.log('User:', presenceData.publisher, 'Channel:', presenceData.channelName);
});
// Listen to topic-related events such as topic creation, update, or deletion
useRtmEvent(engine, 'topic', (topicEvent) => {
console.log('[Signaling] Topic event:', topicEvent.eventType);
console.log('Topic:', topicEvent.topicName, 'Publisher:', topicEvent.publisher);
});
// Listen to updates in shared storage
useRtmEvent(engine, 'storage', (storageData) => {
console.log('[Signaling] Storage event:', storageData.eventType);
console.log('Storage type:', storageData.storageType, 'Channel:', storageData.channelName);
});
// Listen to channel lock or unlock events
useRtmEvent(engine, 'lock', (eventData) => {
console.log('[Signaling] Lock event:', eventData.eventType);
console.log('Lock:', eventData.lockName, 'Channel:', eventData.channelName);
});
// Listen to token expiration warnings
useRtmEvent(engine, 'tokenPrivilegeWillExpire', (channelName) => {
console.log('[Signaling] Token privilege will expire for channel:', channelName);
// Generate and renew token here
});Event listener lifecycle
The useRtmEvent hook provides automatic lifecycle management:
- Automatic registration: Listeners are added when the component mounts
- Automatic cleanup: Listeners are removed when the component unmounts
- Dependency tracking: Hook re-registers listeners when dependencies change
- Memory leak prevention: No manual cleanup required
// Event listeners are automatically managed by the hook
useEffect(() => {
// useRtmEvent hooks automatically register listeners when component mounts
console.log('Component mounted - event listeners active');
return () => {
// Listeners are automatically removed when component unmounts
console.log('Component unmounting - listeners automatically cleaned up');
};
}, []);The useRtmEvent hook is the recommended approach for React Native applications as it follows React best practices and prevents common memory leak issues.
Signaling events
Signaling SDK offers the following events:
| Event Listener | Description | Common Use Cases |
|---|---|---|
message | Receive message notifications from all message channels you have subscribed to, or topic message notifications from stream channels you have joined. Includes channel name, channel type, topic name, sender, message content, and timestamp. | Chat applications, real-time notifications, data synchronization |
linkState | Receive event notifications for client network connection status changes. Includes current state, previous state, reason for change, and error codes. | Connection monitoring, retry logic, user status indicators |
presence | Receive online status event notifications from remote users in subscribed message channels and joined stream channels. Includes user join/leave events, state changes, and user metadata. | User presence indicators, active user lists, status updates |
topic | Receive notifications of topic change events in stream channels you have joined. Includes topic creation, updates, user join/leave topic events. | Stream channel management, topic subscription handling |
storage | Receive channel metadata and user metadata event notifications. Includes metadata updates, deletions, and synchronization events. | Data persistence, shared state management, user profiles |
lock | Receive lock event notifications for distributed resource management. Includes lock acquisition, release, and expiration events. | Resource coordination, mutual exclusion, distributed locks |
tokenPrivilegeWillExpire | Receive event notifications when the client token is about to expire (30 seconds before expiration). | Token refresh, authentication management, session handling |
For details on the parameters passed in by each event, refer the API reference.
To receive message and event notifications when you subscribe to or join channels, you add an event listener. An event listener is triggered by the SDK to inform the client about Signaling events and state changes. The listener enables you to respond to events like successful connection to Signaling, token expiration, received messages, and other presence, storage, and lock events.
Prerequisites
Ensure that you have integrated the Signaling SDK in your project and implemented the framework functionality from the SDK quickstart page.
Implement event listeners
This section shows how to use the Signaling SDK to implement event listeners.
Add an event listener
Signaling uses an IRtmEventHandler instance to process messages and event notifications. Each message and event notification has a corresponding event handler, where you implement your own processing logic. Refer to the following code to create and use an instance of IRtmEventHandler:
class RtmHandler: public IRtmEventHandler {
void onMessageEvent(const MessageEvent &event) {}
void onTopicEvent(const TopicEvent &event) {}
void onConnectionStateChanged(const char *channelName, RTM_CONNECTION_STATE state, RTM_CONNECTION_CHANGE_REASON reason) {}
void onLoginResult(RTM_ERROR_CODE errorCode) {
if (errorCode != RTM_ERROR_OK) {
printf("login rtm failed error is %d reason is %s\n", errorCode, getErrorReason(errorCode));
} else {
printf("login rtm success\n");
}
}
void onStorageEvent(const StorageEvent &event) {}
void onLockEvent(const LockEvent &event) {}
}
RtmConfig cfg;
cfg.appId = "your_appid";
cfg.userId = "your_name";
// Specify the event listener in the client configuration
cfg.eventHandler = new RtmHandler();
// Create an IRtmClient instance
IRtmClient* rtm_client = createAgoraRtmClient();
int ret = rtm_client->initialize(cfg);Remove event listeners
To avoid performance degradation caused by memory leaks, errors, and null pointer exceptions, best practice is to unregister the event handler when you no longer need to use it. For example, if you don't want to use the void onLockEvent(const LockEvent &event) {} event, just delete the definition of the function.
Signaling events
Signaling SDK offers the following events:
| Event Listener | Description |
|---|---|
onMessageEvent | Receive message notifications from all the message channels you have subscribed to, or topic message notifications subscribed to from all the stream channels you have joined. |
onPresenceEvent | Receive online status event notifications from remote users in all the message channels you have subscribed to and stream channels you have joined. |
onTopicEvent | Receive notifications of topic change events in all the stream channels you have joined. |
onStorageEvent | Receive all channel metadata event notifications in all message channels you have subscribed to and stream channels you have joined, as well as user metadata event notifications from all subscribed users. |
onLockEvent | Receive all lock event notifications in the message channels you have subscribed to and stream channels you have joined. |
onConnectionStateChanged | Receive event notifications for client network connection status changes. |
onTokenPrivilegeWillExpire | Receive event notifications that the client token is about to expire. |
For details on the parameters passed in by each event, refer to Event listeners in the API reference.
To receive message and event notifications when you subscribe to or join channels, you add an event listener. An event listener is triggered by the SDK to inform the client about Signaling events and state changes. The listener enables you to respond to events like successful connection to Signaling, token expiration, received messages, and other presence, storage, and lock events.
Prerequisites
Ensure that you have integrated the Signaling SDK in your project and implemented the framework functionality from the SDK quickstart page.
Implement event listeners
This section shows how to use the Signaling SDK to implement event listeners.
Add an event listener
Signaling uses an IRtmEventHandler instance to process messages and event notifications. Each message and event notification has a corresponding event handler, where you implement your own processing logic. Refer to the following code to create and use an instance of IRtmEventHandler:
class RtmHandler: public IRtmEventHandler {
void onMessageEvent(const MessageEvent &event) {}
void onTopicEvent(const TopicEvent &event) {}
void onConnectionStateChanged(const char *channelName, RTM_CONNECTION_STATE state, RTM_CONNECTION_CHANGE_REASON reason) {}
void onLoginResult(RTM_ERROR_CODE errorCode) {
if (errorCode != RTM_ERROR_OK) {
printf("login rtm failed error is %d reason is %s\n", errorCode, getErrorReason(errorCode));
} else {
printf("login rtm success\n");
}
}
void onStorageEvent(const StorageEvent &event) {}
void onLockEvent(const LockEvent &event) {}
}
RtmConfig cfg;
cfg.appId = "your_appid";
cfg.userId = "your_name";
// Specify the event listener in the client configuration
cfg.eventHandler = new RtmHandler();
// Create an IRtmClient instance
IRtmClient* rtm_client = createAgoraRtmClient();
int ret = rtm_client->initialize(cfg);Remove event listeners
To avoid performance degradation caused by memory leaks, errors, and null pointer exceptions, best practice is to unregister the event handler when you no longer need to use it. For example, if you don't want to use the void onLockEvent(const LockEvent &event) {} event, just delete the definition of the function.
Signaling events
Signaling SDK offers the following events:
| Event Listener | Description |
|---|---|
onMessageEvent | Receive message notifications from all the message channels you have subscribed to, or topic message notifications subscribed to from all the stream channels you have joined. |
onPresenceEvent | Receive online status event notifications from remote users in all the message channels you have subscribed to and stream channels you have joined. |
onTopicEvent | Receive notifications of topic change events in all the stream channels you have joined. |
onStorageEvent | Receive all channel metadata event notifications in all message channels you have subscribed to and stream channels you have joined, as well as user metadata event notifications from all subscribed users. |
onLockEvent | Receive all lock event notifications in the message channels you have subscribed to and stream channels you have joined. |
onConnectionStateChanged | Receive event notifications for client network connection status changes. |
onTokenPrivilegeWillExpire | Receive event notifications that the client token is about to expire. |
For details on the parameters passed in by each event, refer to Event listeners in the API reference.
To receive message and event notifications when you subscribe to or join channels, you add an event listener. An event listener is triggered by the SDK to inform the client about Signaling events and state changes. The listener enables you to respond to events like successful connection to Signaling, token expiration, received messages, and other presence, storage, and lock events.
Prerequisites
Ensure that you have integrated the Signaling SDK in your project and implemented the framework functionality from the SDK quickstart page.
Implement event listeners
This section shows how to use the Signaling SDK to implement event listeners.
Add event listeners
Use the RtmClient instance to subscribe to Signaling events:
// Add a message event listener
rtmClient.OnMessageEvent += newMessageEvent =>
{
var channelName = newMessageEvent.channelName;
var channelType = newMessageEvent.channelType;
var topic = newMessageEvent.channelTopic;
var publisher = newMessageEvent.publisher;
var messageType = newMessageEvent.messageType;
var message = newMessageEvent.message;
var customType = newMessageEvent.customType;
// your Logic
};
// Add a presence event listener
rtmClient.OnPresenceEvent += newPresenceEvent =>
{
var channelName = newPresenceEvent.channelName;
var channelType = newPresenceEvent.channelType;
var eventType = newPresenceEvent.type;
var publisher = newPresenceEvent.publisher;
var stateItems = newPresenceEvent.stateItems;
var interval = newPresenceEvent.interval;
var snapshot = newPresenceEvent.snapshot;
// your Logic
};
// Add a topic event listener
rtmClient.OnTopicEvent += newTopicEvent =>
{
var channelName = newTopicEvent.channelName;
var eventType = newTopicEvent.type;
var publisher = newTopicEvent.publisher;
var topicInfos = newTopicEvent.topicInfos;
if (topicInfos != null)
{
// your logic
}
};
// Add a storage event listener
rtmClient.OnStorageEvent += newStorageEvent =>
{
var channelName = newStorageEvent.channelName;
var channelType = newStorageEvent.channelType;
var eventType = newStorageEvent.eventType;
var category = newStorageEvent.target;
var data = newStorageEvent.data;
if (data != null)
{
// your logic
}
};
// Add a lock event listener
rtmClient.OnLockEvent += newLockEvent =>
{
var channelName = newLockEvent.channelName;
var channelType = newLockEvent.channelType;
var eventType = newLockEvent.eventType;
var LockDetail = newLockEvent.lockDetailList;
if( LockDetail != null )
{
// your logic
}
};
// Add a OnConnectionStateChange event listener
rtmClient.OnConnectionStateChanged +=(channelName, state, reason ) =>
{
Debug.Log(string.Format("OnConnectionStateChanged channelName {0}: state:{1} reason:{2}", channelName, state, reason);
// your logic
};
// Add a OnTokenPrivilegeWillExpire event listener
rtmClient.OnTokenPrivilegeWillExpire += channelName =>
{
Debug.Log(string.Format("OnTokenPrivilegeWillExpire channelName {0}", channelName));
// your logic
};Remove event listeners
To avoid performance degradation caused by memory leaks, errors, and null pointer exceptions, best practice is to unsubscribe from events when you no longer need to use them.
private void AddEventsListener()
{
rtmClient.OnMessageEvent += OnMessageEvent;
rtmClient.OnPresenceEvent += OnPresenceEvent;
rtmClient.OnTopicEvent += OnTopicEvent;
rtmClient.OnStorageEvent += OnStorageEvent;
rtmClient.OnLockEvent += OnLockEvent;
rtmClient.OnConnectionStateChanged += OnConnectionStateChanged;
rtmClient.OnTokenPrivilegeWillExpire += OnTokenPrivilegeWillExpire;
}
private void RemoveEventsListener()
{
rtmClient.OnMessageEvent -= OnMessageEvent;
rtmClient.OnPresenceEvent -= OnPresenceEvent;
rtmClient.OnTopicEvent -= OnTopicEvent;
rtmClient.OnStorageEvent -= OnStorageEvent;
rtmClient.OnLockEvent -= OnLockEvent;
rtmClient.OnConnectionStateChanged -= OnConnectionStateChanged;
rtmClient.OnTokenPrivilegeWillExpire -= OnTokenPrivilegeWillExpire;
}
private void OnMessageEvent( MessageEvent Event) { }
private void OnPresenceEvent( PresenceEvent Event) { }
private void OnTopicEvent( TopicEvent Event) { }The RtmClient automatically destroys event handlers when you call Dispose.
Signaling events
Signaling SDK offers the following callbacks:
| Event Listener | Description |
|---|---|
OnMessageEvent | Receive message notifications from all the message channels you have subscribed to, or topic message notifications subscribed to from all the stream channels you have joined. The event payload data includes channel name, channel type, topic name, event sender, message payload, and data type. |
OnPresenceEvent | Receive online status event notifications from remote users in all the message channels you have subscribed to and stream channels you have joined. The event payload data includes channel name, channel type, event type, event sender, and user temporary status data. |
OnTopicEvent | Receive notifications of topic change events in the message channels you have subscribed to and stream channels you have joined. The event payload data includes information such as channel name, event type, topic name, and event sender. |
OnStorageEvent | Receive all channel metadata event notifications in the message channels you have subscribed to and stream channels you have joined, as well as user metadata event notifications from all subscribed users. The event payload data includes information such as channel name, channel type, and event type. |
OnLockEvent | Receive all lock event notifications in the message channels you have subscribed to and stream channels you have joined. The event payload data contains information such as channel name, channel type, event type, and lock details. |
OnConnectionStateChanged | Receive event notifications for client network connection status changes, including channel name, connection status, reason for change, and other information. |
OnTokenPrivilegeWillExpire | Receive event notifications when the client token is about to expire. |
For details on the parameters passed in by each event, refer to Event listeners in the API reference.
