Linux C++

Updated

API reference for the Agora Signaling Linux C++ SDK.

The Signaling SDK API reference is divided into the following sections:

Setup

The API reference for the Signaling SDK documents interface descriptions, methods, basic usage, and return values of the Signaling APIs.

RtmConfig

Description

Use the RtmConfig to set additional properties for Signaling initialization. These configuration properties will take effect throughout the lifecycle of the Signaling client and affect the behavior of the Signaling client.

Method

You can create RtmConfig instances as follows:

RtmConfig config;
config.appId = "your_appid";
config.userId = "your_name";
config.eventHandler = new RtmHandler();
config.areaCode = RTM_AREA_CODE_CN | RTM_AREA_CODE_AS;
config.protocolType = RTM_PROTOCOL_TYPE_TCP_UDP;
config.presenceTimeout = 300;
config.heartbeatInterval = 5;
config.reconnectTimeout = 60;
config.useStringUserId = true;
config.ispPolicyEnabled = false;
config.proxyConfig = proxyConfig;
config.logConfig = logConfig;
config.encryptionConfig = encryptionConfig;
config.privateConfig = privateConfig;
PropertiesTypeRequiredDefaultDescription
appIdconst char*Required-App ID obtained when creating a project in the Agora Console.
userIdconst char*Required-User ID for identify a user or a device. To distinguish each user or device, you need to ensure that the userId parameter is globally unique and remains unchanged throughout the user or device's lifecycle.
areaCodeRTM_AREA_CODEOptionalRTM_AREA_CODE_GLOBService area code, you can choose according to the region where your business is deployed. See RTM_AREA_CODE.
protocolTypeRTM_PROTOCOL_TYPEOptionalRTM_PROTOCOL_TYPE_TCP_UDPProtocol types for message transmission. Signaling by default utilizes one-way TCP and one-way UDP protocols for transmission, but you have the flexibility to modify the protocol types based on your requirements. See RTM_PROTOCOL_TYPE.
presenceTimeoutuint32_tOptional300Presence timeout in seconds, and the value range is [5,300]. This parameter refers the delay imposed by the Signaling server before sending a RTM_PRESENCE_EVENT_TYPE_REMOTE_TIMEOUT event notification to other users once it determines that a client has timed out. If the client reconnects and returns to the channel within the specified time, the Signaling server does not send the RTM_PRESENCE_EVENT_TYPE_REMOTE_TIMEOUT event notification to other participants or delete the temporary user data associated with the user.
heartbeatIntervalintOptional5Heartbeat interval in seconds, and the value range is [5,1800]. This parameter refers to the time interval at which the client sends heartbeat packets to the Signaling server. If the client fails to send heartbeat packets to the Signaling server within the specified time, the Signaling server determines that the client has timed out. Please note that this parameter affects the PCU count, which in turn affects billing.
reconnectTimeoutuint32_tOptional0SDK connection timeout in seconds. The value range is [15,3600]. The default value is 0 which means no timeout; the SDK keeps retrying until successful. This parameter applies to both the initial login to the Signaling service and reconnection after disconnection:
- If the initial login times out, the SDK triggers the onLoginResult callback with errorCode as RTM_ERROR_LOGIN_TIMEOUT, and also triggers the onLinkStateChanged callback with currentState as RTM_LINK_STATE_FAILED and reason as RTM_LINK_CHANGE_REASON_LOGIN_TIMEOUT.
- If reconnection times out, the SDK triggers the onLinkStateChanged callback with currentState as RTM_LINK_STATE_FAILED and reason as RTM_LINK_CHANGE_REASON_RECONNECT_TIMEOUT.
contextvoid*OptionalNULL
- For Android, it is the context of Android Activity.
- For Windows, it is the window handle of the app. Once set, this parameter enables you to connect or disconnect the video devices while they are powered.
useStringUserIdboolOptionaltrueWhether to use string-type user IDs:
- true: Use string-type user IDs.
- false: Use number-type user IDs. The SDK automatically converts string-type user IDs to number-type ones. In this case, the userId parameter must be a numeric string (for example, "123457"), otherwise initialization fails.When using Agora RTC and Signaling products at the same time, it is necessary to ensure that the userId parameter is consistent.
ispPolicyEnabledBoolOptionalfalseWhether to enable the ISP domain policy restriction. In IoT scenarios, devices may be restricted by Internet Service Providers (ISPs). Use this field to set the SDK's connection mode to connect to servers with domains registered with the operator or those in the IP whitelist:
- true: Enable the ISP domain policy restriction. This setting applies to scenarios where IoT devices use IoT SIM cards for network access. The SDK will only connect to servers with domains registered with the operator or those in the IP whitelist.
- false: (Default) Disable the ISP domain policy restriction. This setting applies to most common scenarios.
eventHandlerIRtmEventHandlerRequired-Signaling event notification listener settings. See Event listeners.
logConfigRtmLogConfigOptional-Log configuration properties such as the log storage size, storage path, and level.
proxyConfigRtmProxyConfigOptional-When using the Proxy feature of Signaling, you need to configure this parameter.
encryptionConfigRtmEncryptionConfigOptional-When using the client-side encryption feature of Signaling, you need to configure this parameter.
privateConfigRtmPrivateConfigOptional-When using the private deployment feature of Signaling, you need to configure this parameter.
RtmLogConfig

Use the RtmLogConfig instance to configure and store local log files named agora.log. During the debugging phase, you can greatly improve efficiency by storing and tracking the running status of the app through logs. If you encounter complex problems and need Agora technical support to assist with the investigation, you need to provide the log information. RtmLogConfig contains the following properties:

PropertiesTypeRequiredDefaultDescription
filePathconst char*OptionalNULLLog file storage paths.
fileSizeInKBuint32_tOptional1024Log file size in KB, with a value range of [128,1024].
- If the value you enter is less than 128, the SDK sets the value to 128.
- If the value you enter is greater than 1024, the SDK sets the value to 1024.
levelRTM_LOG_LEVELOptionalRTM_LOG_LEVEL_INFOOutput level of log information. See RTM_LOG_LEVEL.
RtmProxyConfig

Use the RtmProxyConfig instance to set properties related to the client Proxy service. In some restricted network environments, you might need to use this feature.

Caution

You need to keep your Proxy username and password safe. The Signaling SDK does not parse, store, or forward your username and password in any way. In addition, if you modify the Proxy settings during the app running process, the settings will take effect only after restarting the Signaling client.

RtmProxyConfig contains the following properties:

PropertiesTypeRequiredDefaultDescription
serverconst char*Required-Proxy server domain name or IP address.
accountconst char*Required-Proxy login account.
passwordconst char*Required-Proxy login password.
proxyTypeRTM_PROXY_TYPEOptionalRTM_PROXY_TYPE_NONEProxy protocol type. See RTM_PROXY_TYPE.
portuint16_tOptional0Proxy listening port.
RtmEncryptionConfig

Use the RtmEncryptionConfig instance to set the properties required for the client-side encryption. After successfully setting encryption modes, encryption keys, and other related properties, the SDK automatically encrypts and decrypts all messages sent or all statuses set by the user on the client side.

Caution

Once you set the encryption feature, all users must use the same encryption mode and key, otherwise users cannot communicate with each other.

RtmEncryptionConfig contains the following properties:

PropertiesTypeRequiredDefaultDescription
encryptionModeRTM_ENCRYPTION_MODEOptionalRTM_ENCRYPTION_MODE_NONEEncryption mode. See RTM_ENCRYPTION_MODE.
encryptionKeyconst char*Optional-User-defined encryption key, unlimited length. Agora recommends using a 32-byte key.
encryptionKdfSaltuint8_tOptional-User-defined encryption salt, length is 32 bytes. Agora recommends using OpenSSL to generate salt on the server side.

RtmPrivateConfig

Use the RtmPrivateConfig instance to set the properties required for the private deployment.

RtmPrivateConfig contains the following properties:

PropertiesTypeRequiredDefaultDescription
serviceTypeRTM_SERVICE_TYPEOptional-Service type. See RTM_SERVICE_TYPE.
accessPointHostsconst char**Optional-An array of server addresses, where you can fill in domain names or IP addresses.

Basic usage

RtmConfig config;
config.appId = "your_appid";
config.userId = "your_name";
config.eventHandler = new RtmHandler();

config.logConfig.level = RTM_LOG_LEVEL_INFO;
config.logConfig.filePath = "your_path";
config.logConfig.fileSizeInKB = 10 * 1024;

config.proxyConfig.proxyType = RTM_PROXY_TYPE_HTTP;
config.proxyConfig.server = "your_server_address"; // your server address
config.proxyConfig.port = 8080;
config.proxyConfig.account = "your_user_account";
config.proxyConfig.password = "your_password";

uint8_t salt[32] = {1,2,3,4,5};
config.encryptionConfig.encryptionKey = "your_key";
config.encryptionConfig.encryptionMode = RTM_ENCRYPTION_MODE_AES_256_GCM;
memcpy(config.encryptionConfig.encryptionSalt, salt, 32);

std::vector<const char*> hosts;
hosts.push_back("xxx");
config.privateConfig.accessPointHosts = hosts.data();
config.privateConfig.accessPointHostsCount = hosts.size();
config.privateConfig.serviceType = RTM_SERVICE_TYPE_MESSAGE | RTM_SERVICE_TYPE_STREAM;

createAgoraRtmClient

Description

Call the createAgoraRtmClient method to create and initialize the Signaling Client instance.

Information


- You need to create and initialize a client instance before calling other Signaling APIs.
- To distinguish each user or device, you need to ensure that the userId parameter is globally unique and remains unchanged throughout the user or device's lifecycle.

Method

You can create an instance as follows:

AGORA_API IRtmClient* AGORA_CALL createAgoraRtmClient(const RtmConfig& config, int& errorCode);
ParametersTypeRequiredDefaultDescription
configRtmConfigRequired-Initialize the configuration parameters of the Signaling Client. See RtmConfig.
errorCodeint&(Output) Error codes.

Basic usage

RtmConfig config;
config.appId = "your_appid"
config.userId = "your_name";
config.eventHandler = eventHandler_.get();
int errorCode = 0;
rtmClient_ = createAgoraRtmClient(config, errorCode);
if (!rtmClient_ || errorCode != 0) {
    std::cout << RED <<"error creating rtm service!" << std::endl;
    exit(0);
}

Return value

  • If the method call succeeds, the SDK creates a Signaling client instance for subsequent calls to other Signaling APIs.

  • If the method call fails, the SDK returns NULL.

Event Listeners

Description

Signaling has a total of 8 types of event notifications, as shown in the following table:

Event TypeDescription
onMessageEventReceive message notifications from all subscribed Message Channels or topic message notifications subscribed to, in all Stream Channels you join. See MessageEvent .
onPresenceEventReceive presence event notifications in subscribed message channels and joined stream channels. See PresenceEvent
onTopicEventReceive all topic event notifications in joined stream channels. See TopicEvent
onStorageEventReceive channel metadata event notifications in subscribed message channels and joined stream channels, and the user metadata event notification of the subscribed users. See StorageEvent
onLockEventReceive lock event notifications in subscribed message channels and joined stream channels. See LockEvent
onConnectionStateChanged(Deprecated) Receive event notifications when client connection status changes. For details, see RTM_CONNECTION_STATE and RTM_CONNECTION_CHANGE_REASON.
onLinkStateEventReceive event notifications when client connection status changes. See LinkStateEvent.
onTokenPrivilegeWillExpireReceive event notifications when the client tokens are about to expire.

Add event listeners

Add an event listener object as follows:

 // only need override the event which you want to receive
class RtmEventHandler: 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) {}
    void onStorageEvent(const StorageEvent &event) {}
    void onLockEvent(const LockEvent &event) {}
    void onLinkStateEvent(const LinkStateEvent& event) {}
    ...
};

RtmConfig config;
config.eventHandler = new RtmEventHandler();
MessageEvent

Message event.

MessageEvent contains the following properties:

PropertiesTypeDescription
channelTypeRTM_CHANNEL_TYPEChannel types. See RTM_CHANNEL_TYPE.
messageTypeRTM_MESSAGE_TYPEMessage type. See RTM_MESSAGE_TYPE.
channelNameconst char*Channel name.
channelTopicconst char*Topic name.
messageconst char*Message.
messageLengthsize_tMessage length.
publisherconst char*User ID of the message publisher.
customTypeconst char*A user-defined field. Only supports string type.
timestampuint64_tThe timestamp when the event occurs.
PresenceEvent

User presence event.

PresenceEvent contains the following properties:

PropertiesTypeDescription
typeRTM_PRESENCE_EVENT_TYPEPresence event type. See RTM_PRESENCE_EVENT_TYPE.
channelTypeRTM_CHANNEL_TYPEChannel types. See RTM_CHANNEL_TYPE.
channelNameconst char*Channel name.
publisherconst char*User ID of the message publisher.
stateItemsconst StateItem*Key-value pair that identifies the user's presence state.
stateItemCountsize_tCount of state items.
intervalIntervalInfoIn the Interval state, the aggregated incremental information of event notifications such as user joining, leaving, timeout, and status change in the previous period of the current channel.
snapshotSnapshotInfoWhen the user first joins the channel, the server pushes the snapshot data of all users in the current channel and their statuses to the user.
timestampuint64_tThe timestamp when the event occurs.

IntervalInfo contains the following properties:

PropertiesTypeDescription
joinUserListUserListList of users who joined the channel in the previous cycle.
leaveUserListUserListList of users who left the channel in the previous cycle.
timeoutUserListUserListList of users who timed out joining the channel in the previous cycle.
userStateListUserState*List of users whose status has changed in the previous cycle. Contains user ID and status key-value pairs.
userStateCountsize_tNumber of users whose status has changed in the previous cycle.

SnapshotInfo contains the following properties:

PropertiesTypeDescription
userStateListUserState*Snapshot information of the user when first joining the channel, including user ID and key-value pairs of status.
userCountsize_tNumber of users in the channel when a user joins for the first time.

UserList contains the following properties:

PropertiesTypeDescription
usersconst char**User list.
userCountsize_tUser count.

UserState contains the following properties:

PropertiesTypeDescription
userIdconst char*User ID.
statesconst StateItem*List of online users and their temporary state information in a specified channel.
statesCountsize_tState count.

StateItem data type contains the following properties:

PropertiesTypeDescription
keyconst char*Key of the user state. If the specified key already exists, the SDK overwrites the value; if the specified key does not exist, the SDK creates the key-value pair.
valueconst char*Value of the user state.
TopicEvent

Topic event.

TopicEvent contains the following properties:

PropertiesTypeDescription
typeRTM_TOPIC_EVENT_TYPETopic event type. See RTM_TOPIC_EVENT_TYPE.
channelNameconst char*Channel name.
publisherconst char*User ID.
topicInfosconst TopicInfo*Topic information.
topicInfoCountsize_tCount of topic information.
timestampuint64_tThe timestamp when the event occurs.

TopicInfo data type contains the following properties:

PropertiesTypeDescription
topicconst char*Topic name.
publishersArrayList&lt;PublisherInfo&gt;Message publisher array.
publisherCountsize_tCount of the message publisher.

PublisherInfo data type contains the following properties:

PropertiesTypeDescription
publisherUserIdconst char*User ID of the message publisher.
publisherMetaconst char*Metadata of the message publisher.
StorageEvent

Storage event.

StorageEvent contains the following properties:

PropertiesTypeDescription
channelTypeRTM_CHANNEL_TYPEChannel types. See RTM_CHANNEL_TYPE.
storageTypeRTM_STORAGE_TYPEStorage type. See RTM_STORAGE_TYPE.
eventTypeRTM_STORAGE_EVENT_TYPEStorage event type. See RTM_STORAGE_EVENT_TYPE.
targetconst char*User ID or channel name.
dataMetadata*Metadata item. See Metadata.
timestampuint64_tThe timestamp when the event occurs.
LockEvent

Lock event.

LockEvent contains the following properties:

PropertiesTypeDescription
channelTypeRTM_CHANNEL_TYPEChannel types. See RTM_CHANNEL_TYPE.
eventTypeRTM_LOCK_EVENT_TYPELock event type. See RTM_LOCK_EVENT_TYPE.
channelNameconst char*Channel name.
lockDetailListconst LockDetail*Details of lock.
countsize_tLock count.
timestampuint64_tThe timestamp when the event occurs.

The LockDetail data type contains the following properties:

PropertiesTypeDescription
lockNameconst char*Lock name.
ownerconst char*The ID of the user who has a lock.
ttluint32_tThe expiration time of the lock. The value is in seconds, ranging from [10 to 300]. When the user who owns the lock goes offline, if the user returns to the channel within the time they can still use the lock; otherwise, the lock is released and the users who listen for the onLockEvent event receives the RTM_LOCK_EVENT_TYPE_LOCK_RELEASED event.
LinkStateEvent

SDK link state event.

LinkStateEvent data type contains the following properties:

ParametersTypeDescription
currentStateRTM_LINK_STATEThe current link state. See RTM_LINK_STATE.
previousStateRTM_LINK_STATEThe previous link state. See RTM_LINK_STATE.
serviceTypeRTM_SERVICE_TYPEThe network connection type. See RTM_SERVICE_TYPE.
operationRTM_LINK_OPERATIONThe operation that triggered the current state transition. See RTM_LINK_OPERATION.
reasonCodeRTM_LINK_STATE_CHANGE_REASONThe reason for this state transition. See RTM_LINK_STATE_CHANGE_REASON.
reasonconst char*The reason for the current state transition. This parameter will be deprecated in the future, please use the reasonCode parameter instead.
affectedChannelsconst char**The channels affected by the current state transition.
affectedChannelCountsize_tThe number of channels affected by the current state transition.
unrestoredChannelsconst char**The information about the channels to which subscription or joining has not been restored, including the channel name, channel type, and temporary state data in the channel. Typically, this information is empty.
unrestoredChannelCountsize_tThe number of channels to which subscription or joining has not been restored.
isResumedboolWithin 2 minutes of the disconnection, whether the state transitions from RTM_LINK_STATE_DISCONNECTED to RTM_LINK_STATE_CONNECTED. true refers to the state has transitioned.
timestampuint64_tThe timestamp when the event occurs.

login

Description

After creating and initializing the Signaling instance, you need to perform the login operation to log in to the Signaling service. After successful login, the client establishes a long connection with the Signaling server, and then the SDK allows the client to access Signaling resources.

Information

After the user successfully logs in to the Signaling service, the PCU of the application increases, which affects your billing data.

Method

You can log in to the Signaling system as follows:

virtual void login(const char* token, uint64_t& requestId) = 0;
ParametersTypeRequiredDefaultDescription
tokenconst char*Required-The token used for logining to the Signaling system.
- If your project enables token authentication, you can provide either the Signaling temporary token or the Signaling token generated by your token server. See User authentication and Deploy Signaling token generator.
- If your project does not enable token authentication, you can enter an empty string or the App ID of a project that enables Signaling services.
requestIduint64_t&Required-(Output) Request identifier. Use this parameter to identify and process the corresponding request.

Asynchronous callback

After calling this method, the SDK triggers the onLoginResult callback and return the API execution result through the following parameters:

ParametersTypeDescription
requestIdconst uint64_tRequest identifier.
errorCodeRTM_ERROR_CODEError codes.

Basic usage

// Method call
uint64_t requestId;
rtmClient->login("your_token", requestId);
// Asynchronous callback
class RtmEventHandler : public IRtmEventHandler {
    void onLoginResult(const uint64_t requestId, 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");
        }
    }
};

logout

Description

When you no longer need to operate, you can log out of the system. This operation affects the PCU item in your billing data.

Method

You can log out as follows:

virtual void logout(uint64_t& requestId) = 0;
ParametersTypeRequiredDefaultDescription
requestIduint64_t&Required-(Output) Request identifier. Use this parameter to identify and process the corresponding request.

Asynchronous callback

After calling this method, the SDK triggers the onLogoutResult callback and return the API execution result through the following parameters:

ParametersTypeDescription
requestIdconst uint64_tRequest identifier.
errorCodeRTM_ERROR_CODEError codes.

Basic usage

uint64_t requestId;
rtmClient->logout(requestId);
 // Asynchronous callback
class RtmEventHandler : public IRtmEventHandler {
    void onLogoutResult(const uint64_t requestId, RTM_ERROR_CODE errorCode) {
        if (errorCode != RTM_ERROR_OK) {
            printf("logout rtm failed error is %d reason is %s\n", errorCode, getErrorReason(errorCode));
        } else {
            printf("logout rtm success\n");
        }
    }
};

Synchronous return value

  • 0: Success.
  • < 0: Failure.

releaseLock

Description

Once you no longer need the Signaling service, it is best to destroy the IRtmClient instance. Doing so protects you from the performance degradation caused by memory leaks, errors, and exceptions.

Method

You can destroy the IRtmClient instance as follows:

virtual int release() = 0;

Basic usage

rtmClient->release();

Return value

  • 0: Success.
  • < 0: Failure.

User authentication

Authentication is the process of validating the identity of each user before they access a system. Agora uses digital tokens to authenticate users and their privileges.

Signaling provides 3 types of channels: message channels, user channels and stream channels. Different types of channels require different types of tokens:

  • For message channels and user channels: When logging in to the Signaling system using the login method, you only need to pass the token that enables Signaling service.
  • For stream channels: In addition to the Signaling token, when joining a stream channel using the joinTopic method, you also need to pass the token that enables RTC service.

The token is valid for up to 24 hours. Agora recommends that you update the token before it expires. This article describes how to update the token.

For more information on generating and using tokens, see Secure authentication with tokens.

IRtmClient::renewToken

Description

Call the IRtmClient::renewToken method to renew the Signaling token.

To ensure timely token updates, Agora recommends listening for the onTokenPrivilegeWillExpire callback. See Event listeners for details. Once you successfully add the event listener, when the Signaling token is about to expire within 30 seconds, the SDK triggers the onTokenPrivilegeWillExpire callback to notify the user about the impending token expiration.

Upon receiving this callback, you can generate a new Signaling token on the server-side and call the renewToken method to provide the SDK with the newly generated Signaling token.

Method

You can call the IRtmClient::renewToken method as follows:

virtual void renewToken(const char* token, uint64_t& requestId) = 0;
ParametersTypeRequiredDefaultDescription
tokenstringRequired-The newly generated Signaling token.
requestIduint64_t&Required-(Output) Request identifier. Use this parameter to identify and process the corresponding request.

Asynchronous callback

After calling this method, the SDK triggers the onRenewTokenResult callback and return the API execution result through the following parameters:

ParametersTypeDescription
requestIdconst uint64_tRequest identifier.
serverTypeRTM_SERVICE_TYPEService type. See RTM_SERVICE_TYPE.
channelNameconst char*Channel name.
errorCodeRTM_ERROR_CODEError codes.

Basic usage

rtmClient->renewToken("your token");

IStreamChannel::renewToken

Description

Call the IStreamChannel::renewToken method to renew the RTC token.

To ensure timely token updates, Agora recommends listening for the onTokenPrivilegeWillExpire callback. See Event listeners for details. Once you successfully add the event listener, when the RTC token is about to expire within 30 seconds, the SDK triggers the onTokenPrivilegeWillExpire callback to notify the user about the impending token expiration.

Upon receiving this callback, you can generate a new RTC token on the server-side and call the renewToken method to provide the SDK with the newly generated RTC token.

Method

You can call the IStreamChannel::renewToken method as follows:

virtual void renewToken(const char* token, uint64_t& requestId) = 0;
ParametersTypeRequiredDefaultDescription
tokenstringRequired-The newly generated RTC token.
requestIduint64_t&Required-(Output) Request identifier. Use this parameter to identify and process the corresponding request.

Asynchronous callback

After calling this method, the SDK triggers the onRenewTokenResult callback and return the API execution result through the following parameters:

ParametersTypeDescription
requestIdconst uint64_tRequest identifier.
serverTypeRTM_SERVICE_TYPEService type. See RTM_SERVICE_TYPE.
channelNameconst char*Channel name.
errorCodeRTM_ERROR_CODEError codes.

Basic usage

uint64_t requestId;
streamChannel->renewToken("your token", requestId);

Channels

Signaling provides a highly efficient channel management mechanism for data transmission. Any user who subscribes or joins a channel can receive messages and events transmitted within 100 milliseconds. Signaling allows clients to subscribe to hundreds or even thousands of channels. Most Signaling APIs perform actions such as sending, receiving, and encrypting based on channels.

Based on capabilities of Agora, Signaling channels are divided into two types to match different application use-cases:

  • Message Channel: Follows the industry-standard Pub/Sub (publish/subscribe) mode. You can send and receive messages within the channel by subscribing to a channel, and do not need to create the channel in advance. There is no limit to the number of publishers and subscribers in a channel.
  • Stream Channel: Follows a concept similar to the observer pattern in the industry, where users need to create and join a channel before sending and receiving messages. You can create different topics in the channel, and messages are organized and managed through topics.

IRtmClient Signaling client instance

subscribeTopic

Description

Signaling provides event notification capabilities for messages and states. By listening for callbacks, you can receive messages and events within subscribed channels. For information on how to add and set event listeners, see Event Listeners.

By calling the subscribeTopic method, the client can subscribe to a message channel and start receiving messages and event notifications within the channel. After successfully calling this method, users who subscribe to the channel and enable the presence event listener can receive a RTM_PRESENCE_EVENT_TYPE_REMOTE_JOIN_CHANNEL type of the onPresenceEvent event. See Event Listeners.

Information

This method only applies to the message channel.

Method

You can call the subscribeTopic method as follows:

virtual void subscribe(const char* channelName, const SubscribeOptions& options, uint64_t& requestId) = 0;
ParametersTypeRequiredDefaultDescription
channelNameconst char*Required-Channel name.
optionsconst SubscribeOptions&Required-Options for subscribing to a channel.
requestIduint64_t&Required-(Output) Request identifier. Use this parameter to identify and process the corresponding request.

SubscribeOptions contains the following properties:

PropertiesTypeRequiredDefaultDescription
withMessageboolOptionaltrueWhether to subscribe to message event notifications in the channel.
withPresenceboolOptionaltrueWhether to subscribe to presence event notifications in the channel.
withMetadataboolOptionalfalseWhether to subscribe to storage event notifications in the channel.
withLockboolOptionalfalseWhether to subscribe to lock event notifications in the channel.
beQuietboolOptionalfalseWhether to set the silent mode. If you set this parameter as true, the SDK has the following behaviors:
- You can still receive other users' event notifications.
- Event notifications related to your channel activity such as subscribing or unsubscribing the channel, and actions related to setting, getting, or deleting temporary user states, can not be broadcasted to other users.
- When calling the getOnlineUsers method, your information can not be found.
- When calling the getUserChannels method, channels that you subscribe in silent mode can not be detected.

Asynchronous callback

After calling this method, the SDK triggers the onSubscribeResult callback and return the API execution result through the following parameters:

ParametersTypeDescription
requestIdconst uint64_tRequest identifier.
channelNameconst char*Channel name.
errorCodeRTM_ERROR_CODEError codes.

Basic usage

 // Method call
SubscribeOptions options;
options.withLock = true;
options.withMessage = true;
options.withMetadata = true;
options.withPresence = true;
options.beQuiet = false;

uint64_t requestId;
rtmClient->subscribe("channelName", options, requestId);
 // Asynchronous callback
class RtmEventHandler : public IRtmEventHandler {
    void onSubscribeResult(const uint64_t requestId, const char *channelName, RTM_ERROR_CODE errorCode) {
        if (errorCode != RTM_ERROR_OK) {
            printf("subscribe rtm channel failed error is %d reason is %s\n", errorCode, getErrorReason(errorCode));
        } else {
            printf("subscribe rtm channel %s success\n", channelName);
        }
    }
};

unsubscribeTopic

Description

If you no longer need to subscribe to a channel, you can call the unsubscribeTopic method to unsubscribe from the channel. After successfully calling this method, users who subscribe to the channel and enable event listeners can receive the RTM_PRESENCE_EVENT_TYPE_REMOTE_LEAVE_CHANNEL type of the onPresenceEvent event notification. See Event Listeners.

Information

This method only applies to the message channel.

Method

You can call the unsubscribeTopic method as follows:

virtual void unsubscribe(const char* channelName, uint64_t& requestId) = 0;
ParametersTypeRequiredDefaultDescription
channelNameconst char*Required-Channel name.
requestIduint64_t&Required-(Output) Request identifier. Use this parameter to identify and process the corresponding request.

Asynchronous callback

After calling this method, the SDK triggers the onUnsubscribeResult callback and return the API execution result through the following parameters:

ParametersTypeDescription
requestIdconst uint64_tRequest identifier.
channelNameconst char*Channel name.
errorCodeRTM_ERROR_CODEError codes.

Basic usage

 // Method call
uint64_t requestId;
rtm_client->unsubscribe("channelName", requestId);
 // Asynchronous callback
class RtmEventHandler : public IRtmEventHandler {
    void onUnsubscribeResult(const uint64_t requestId, const char* channelName, RTM_ERROR_CODE errorCode) override {
        if (errorCode != RTM_ERROR_OK) {
            printf("unsubscribe rtm channel failed error is %d reason is %s\n", errorCode, getErrorReason(errorCode));
        } else {
            printf("unsubscribe rtm channel %s success\n", channelName);
        }
    }
};

createAgoraRtmClient

Description

Before using a stream channel, you need to call the createAgoraRtmClient method to create the IStreamChannel instance. After successfully creating the instance, you can call its relevant methods to implement functions, such as joining the channel, leaving the channel, sending messages in a topic, and subscribing to messages in a topic.

Information

This method only applies to the stream channel.

Method

You can call the createAgoraRtmClient method as follows:

virtual IStreamChannel* createStreamChannel(const char* channelName, int& errorCode) = 0;
ParametersTypeRequiredDefaultDescription
channelNameconst char*Required-Channel name.
errorCodeint&Required-(Output) Error codes.

Basic usage

int errorCode = 0;
IStreamChannel* streamChannel = rtmClient->createStreamChannel("channelName", errorCode);
if (streamChannel == nullptr || errorCode != 0) {
    printf("create stream channel failed");
} else {
    printf("create stream channel success");
}

Return value

  • Success: Returns an instance of IStreamChannel to use for subsequent calls to other stream channel APIs.
  • Failure: Returns NULL.

IStreamChannel Stream channel instance

joinTopic

Description

After successfully creating a stream channel, you can call the joinTopic method to join the stream channel.

Once you join the channel, you can implement channel-related functions. At this point, users who subscribe to the channel and add event listeners can receive the following event notifications:

  • For the local user:
    • The RTM_PRESENCE_EVENT_TYPE_SNAPSHOT type of the onPresenceEvent event.
    • The RTM_TOPIC_EVENT_TYPE_SNAPSHOT type of the onTopicEvent event.
  • For remote users: The RTM_PRESENCE_EVENT_TYPE_REMOTE_JOIN_CHANNEL type of the onPresenceEvent event.

Information

This method only applies to the stream channel.

Method

You can call the joinTopic method as follows:

virtual void join(const JoinChannelOptions& options, uint64_t& requestId) = 0;
ParametersTypeRequiredDefaultDescription
optionsconst JoinChannelOptions&Required-Options for joining a channel.
requestIduint64_t&Required-(Output) Request identifier. Use this parameter to identify and process the corresponding request.

The JoinChannelOptions data type contains the following properties:

PropertiesTypeRequiredDefaultDescription
tokenconst char*Required-The token used for joining a stream channel.
- If your project enables token authentication, you can provide either the RTC temporary token or the RTC token generated by your token server.
- If your project does not enable token authentication, you can enter an empty string or the App ID of a project that enables RTC and Signaling services.
withPresenceboolOptionaltrueWhether to subscribe to presence event notifications in the channel.
withMetadataboolOptionalfalseWhether to subscribe to storage event notifications in the channel.
withLockboolOptionalfalseWhether to subscribe to lock event notifications in the channel.
beQuietboolOptionalfalseWhether to set the silent mode. If you set this parameter as true, the SDK has the following behaviors:
- You can still receive other users' event notifications.
- Event notifications related to your channel activity such as joining or leaving the channel, and actions related to setting, getting, or deleting temporary user states, can not be broadcasted to other users.
- When calling the getOnlineUsers method, your information can not be found.
- When calling the getUserChannels method, channels that you subscribe in silent mode can not be detected.

Asynchronous callback

After calling this method, the SDK triggers the onJoinResult callback and return the API execution result through the following parameters:

ParametersTypeDescription
requestIdconst uint64_tRequest identifier.
channelNameconst char*Channel name.
userIdconst char*User ID.
errorCodeRTM_ERROR_CODEError codes.

Basic usage

 // Method call
JoinChannelOptions options;
options.token = "your_token";
options.withLock = false;
options.withMetadata = false;
options.withPresence = true;
options.beQuiet = false;
uint64_t requestId;
streamChannel->join(options, requestId);
 // Asynchronous callback
class RtmEventHandler : public IRtmEventHandler {
    void onJoinResult(const uint64_t requestId, const char *channelName, const char *userId, RTM_ERROR_CODE errorCode) {
        if (errorCode != RTM_ERROR_OK) {
            printf("join rtm channel failed error is %d reason is %s\n", errorCode, getErrorReason(errorCode));
        } else {
            printf("join rtm channel %s success\n", channelName);
        }
    }
};

leaveTopic

Description

If you no longer need to stay in a channel, you can call the leaveTopic method to leave the channel. After leaving the channel, you can no longer receive any messages, states, or event notifications from this channel. At the same time, you can no loger be the topic publisher or subscriber of all topics. If you want to restore your previous publisher role and subscribing relationship, you need to call joinTopic, joinTopic and subscribeTopic methods in order.

After successfully leaving the channel, remote users in the channel can receive the RTM_PRESENCE_EVENT_TYPE_REMOTE_LEAVE_CHANNEL type of the onPresenceEvent event notification. For details, see Event Listeners.

Information

This method only applies to the stream channel.

Method

You can call the leaveTopic method as follows:

virtual void leave(uint64_t& requestId) = 0;
ParametersTypeRequiredDefaultDescription
requestIduint64_t&Required-(Output) Request identifier. Use this parameter to identify and process the corresponding request.

Asynchronous callback

After calling this method, the SDK triggers the onLeaveResult callback and return the API execution result through the following parameters:

ParametersTypeDescription
requestIdconst uint64_tRequest identifier.
channelNameconst char*Channel name.
userIdconst char*User ID.
errorCodeRTM_ERROR_CODEError codes.

Basic usage

 // Method call
uint64_t requestId;
streamChannel->leave(requestId);
 // Asynchronous callback
class RtmEventHandler : public IRtmEventHandler {
    void onLeaveResult(const uint64_t requestId, const char *channelName, const char *userId, RTM_ERROR_CODE errorCode) {
        if (errorCode != RTM_ERROR_OK) {
           printf("leave rtm channel failed error is %d reason is %s\n", errorCode, getErrorReason(errorCode));
        } else {
            printf("leave rtm channel %s success\n", channelName);
        }
    }
};

releaseLock

Description

If you no longer need a channel, you can call the releaseLock method to destroy the corresponding stream channel instance and release resources. Calling the releaseLock method does not destroy the stream channel, and it can be re-joined later by calling createAgoraRtmClient and joinTopic again.

Information

This method only applies to the stream channel. If you don't call leaveTopic to leave the channel before directly calling releaseLock to destroy the stream channel instance, the SDK automatically calls the leaveTopic and triggers the corresponding event.

Method

You can call the releaseLock method as follows:

virtual int release() = 0;

Basic usage

int ret = streamChannel->release();

Return value

  • 0: Success.
  • < 0: Failure.

Topics

Topic is a data stream management mechanism in stream channels. Users can use topics to subscribe to and distribute data streams, as well as notify events in data streams in stream channels.

Information

Topics only exist in stream channels. Therefore, before using relevant features, you need to create the IStreamChannel instance.

IStreamChannel Stream channel instance

joinTopic

Description

The purpose of joining a topic is to register as one of the message publishers for the topic, so that the user can send messages in the topic. This operation does not affect whether or not the user becomes a subscriber to the topic.

Information

  • Currently, Signaling supports a single client joining up to 8 topics in the same stream channel at a time.
  • Before joining a topic, a user needs to create the IStreamChannel instance and call the joinTopic method to join the channel.

After successfully joining a topic, users who subscribe to that topic and add event listeners can receive the RTM_TOPIC_EVENT_TYPE_REMOTE_JOIN_TOPIC type of the onTopicEvent event notification. For details, see Event Listeners.

Method

You can call the joinTopic method as follows:

virtual void joinTopic(const char* topic, const JoinTopicOptions& options, uint64_t& requestId) = 0;
ParametersTypeRequiredDefaultDescription
topicconst char*Required-Topic name.
optionsconst JoinTopicOptions&Required-Options for joining a topic.
requestIduint64_t&Required-(Output) Request identifier. Use this parameter to identify and process the corresponding request.

The JoinTopicOptions data type contains the following properties:

PropertiesTypeRequiredDefaultDescription
qosRTM_MESSAGE_QOSOptionalRTM_MESSAGE_QOS_UNORDEREDWhether the data transmitted in the topic is ordered. See RTM_MESSAGE_QOS.
priorityRTM_MESSAGE_PRIORITYOptionalRTM_MESSAGE_PRIORITY_NORMALThe priority of data transmission in the topic compared to other topics in the same channel. See RTM_MESSAGE_PRIORITY.
metaconst char*OptionalNULLAdds additional metadata when joining the topic.
syncWithMediaboolOptionalfalseWhether the data sent in this topic is synchronized (timestamp-aligned) with the RTC audio and video data stream of the common channel.

Asynchronous callback

After calling this method, the SDK triggers the onJoinTopicResult callback and return the API execution result through the following parameters:

ParametersTypeDescription
requestIdconst uint64_tRequest identifier.
channelNameconst char*Channel name.
userIdconst char*User ID.
topicconst char*Topic name.
metaconst char*Adds additional metadata when joining the topic.
errorCodeRTM_ERROR_CODEError codes.

Basic usage

// Method call
JoinTopicOptions options;
options.qos = RTM_MESSAGE_QOS_ORDERED;

uint64_t requestId;
stream_channel->joinTopic("topicName", options, requestId);
// Asynchronous callback
class RtmEventHandler : public IRtmEventHandler {
    void onJoinTopicResult(const uint64_t requestId, const char *channelName, const char *userId, const char *topic, const char *meta, RTM_ERROR_CODE errorCode) override {
        if (errorCode != RTM_ERROR_OK) {
            printf("JoinTopic failed error is %d reason is %s\n", errorCode, getErrorReason(errorCode));
        } else {
            printf("JoinTopic success\n");
        }
    }
};

publishTopicMessage

Description

Use the publishTopicMessage method to send messages to a topic. Users who have subscribed to the topic and the message publisher in the channel can receive the message within 100 milliseconds. Before calling the publishTopicMessage method, users need to join the stream channel, and then register as a message publisher for that topic by calling the joinTopic method.

The messages sent by users are encrypted with TLS during transmission, and data link encryption is enabled by default and cannot be disabled. To achieve a higher level of data security, users can also enable client encryption during initialization. For details, see Setup.

Method

You can call the publishTopicMessage[1/2] and publishTopicMessage[2/2] method as follows:

virtual void publishTopicMessage(const char* topic, const char* message, size_t length, const TopicMessageOptions& option, uint64_t& requestId) = 0;
ParametersTypeRequiredDefaultDescription
topicconst char*Required-Topic name.
messageconst char*Required-Message payload.
lengthconst size_tRequired-Length of message payload.
optionsconst TopicMessageOptions&Required-Message options.
requestIduint64_t&Required-(Output) Request identifier. Use this parameter to identify and process the corresponding request.

The TopicMessageOptions data type contains the following properties:

PropertiesTypeRequiredDefaultDescription
messageTypeRTM_MESSAGE_TYPEOptionalRTM_MESSAGE_TYPE_BINARYMessage type. See RTM_MESSAGE_TYPE.
sendTsuint64_tOptional0The timestamp when the SDK sends a message. This parameter is only valid when you set syncWithMedia = true in the joinTopic method. The SDK synchronizes data with RTC audio and video streams based on this timestamp.
customTypeconst char*OptionalNULLA user-defined field. Only supports string type.

Asynchronous callback

After calling this method, the SDK triggers the onPublishTopicMessageResult callback and return the API execution result through the following parameters:

ParametersTypeDescription
requestIdconst uint64_tRequest identifier.
channelNameconst char*Channel name.
topicconst char*Topic name.
errorCodeRTM_ERROR_CODEError codes.

Basic usage

Example 1: Send string messages to a specified channel.

std::string message = "hello world";
TopicMessageOptions options;
options.messageType = RTM_MESSAGE_TYPE_STRING;
options.customType = "Text";

uint64_t requestId;
streamChannel->publishTopicMessage("topicName", message.c_str(), message.size(), options, requestId);

Example 2: Send byte messages to a specified channel.

TopicMessageOptions options;
options.messageType = RTM_MESSAGE_TYPE_BINARY;
options.customType = "ByteArray";

char message[5] = {0x00, 0x01, 0x02, 0x03, 0x04};

uint64_t requestId;
stream_channel->publishTopicMessage("topic_name", message, 5, options, requestId);

leaveTopic

Description

When you no longer need to publish messages to a topic, to release resources, you can call the leaveTopic method to unregister as a message publisher for that topic. This method does not affect whether or not you subscribe to that topic or any other operations performed by other users on that topic.

After successfully calling this method, users who subscribe to the channel and enable event listeners can receive the RTM_TOPIC_EVENT_TYPE_REMOTE_LEAVE_TOPIC type of the onTopicEvent event notification. See Event Listeners.

Method

You can call the leaveTopic method as follows:

virtual void leaveTopic(const char* topic, uint64_t& requestId) = 0;
ParametersTypeRequiredDefaultDescription
topicconst char*Required-Topic name.
requestIduint64_t&Required-(Output) Request identifier. Use this parameter to identify and process the corresponding request.

Asynchronous callback

After calling this method, the SDK triggers the onLeaveTopicResult callback and return the API execution result through the following parameters:

ParametersTypeDescription
requestIdconst uint64_tRequest identifier.
channelNameconst char*Channel name.
userIdconst char*User ID.
topicconst char*Topic name.
metaconst char*Adds additional metadata when joining the topic.
errorCodeRTM_ERROR_CODEError codes.

Basic usage

// Method call
uint64_t requestId;
streamChannel->leaveTopic("topicName", requestId);
// Asynchronous callback
class RtmEventHandler : public IRtmEventHandler {
    void onLeaveTopicResult(const uint64_t requestId, const char *channelName, const char *userId, const char *topic, const char *meta, RTM_ERROR_CODE errorCode) override
    {
        if (errorCode != RTM_ERROR_OK) {
            printf("LeaveTopic failed error is %d reason is %s\n", errorCode, getErrorReason(errorCode));
        } else {
            printf("LeaveTopic success\n");
        }
    }
};

subscribeTopic

Description

After joining the channel, you can call the subscribeTopic method to subscribe to the message publisher of the topic in the channel.

subscribeTopic is an incremental method. For example, if you call this method for the first time with a subscribing list of [UserA, UserB], and then call it again with a subscribing list of [UserB, UserC], the final successful subscribing result is [UserA, UserB, UserC].

A user can subscribe to a maximum of 50 topics in each channel, and a maximum of 64 message publishers in each topic.

Method

You can call the subscribeTopic method as follows:

virtual void subscribeTopic(const char* topic, const TopicOptions& options, uint64_t& requestId) = 0;
ParametersTypeRequiredDefaultDescription
topicconst char*Required-Topic name.
optionsconst TopicOptions&Required-Options for subscribing to a topic.
requestIduint64_t&Required-(Output) Request identifier. Use this parameter to identify and process the corresponding request.

The TopicOptions data type contains the following properties:

PropertiesTypeRequiredDefaultDescription
usersconst char**OptionalNULLA list of UserId of message publishers that you want to subscribe to. If you do not set this property, you can randomly subscribe to up to 64 users by default.
userCountsize_tOptional0User count.

Asynchronous callback

After calling this method, the SDK triggers the onSubscribeTopicResult callback and return the API execution result through the following parameters:

ParametersTypeDescription
requestIdconst uint64_tRequest identifier.
channelNameconst char*Channel name.
userIdconst char*User ID.
topicconst char*Topic name.
succeedUsersUserListA list of successfully subscribed users.
failedUsersUserListA list of users that the SDK fails to subscribe to.
errorCodeRTM_ERROR_CODEError codes.

The UserList data type contains the following properties:

PropertiesTypeDescription
usersconst char**User list of publishers.
userCountsize_tCount of publishers.

Basic usage

Example 1: Subscribe to the specified message publisher in the topic.

std::vector<const char*> users;
users.push_back("UserA");
users.push_back("UserB");

TopicOptions options;
options.users = users.data();
options.userCount = users.size();

uint64_t requestId;
streamChannel->subscribeTopic("topicName", options, requestId);

Example 2: Randomly subscribe to 64 message publishers in the topic.

TopicOptions options;

uint64_t requestId;
streamChannel->subscribeTopic("topicName", options, requestId);

Example 3: Asynchronous callback.

// Asynchronous callback
class RtmEventHandler : public IRtmEventHandler {
    void onSubscribeTopicResult(const uint64_t requestId, const char *channelName, const char *userId, const char *topic, UserList succeedUsers, UserList failedUsers, RTM_ERROR_CODE errorCode) override {
        if (errorCode != RTM_ERROR_OK) {
            printf("SubscribeTopic failed error is %d reason is %s\n", errorCode, getErrorReason(errorCode));
        } else {
            printf("SubscribeTopic success\n");
        }
    }
};

unsubscribeTopic

Description

If you are no longer interested in a specified topic, or no longer need to subscribe to one or more message publishers in the topic, you can call the unsubscribeTopic method to unsubscribe from the topic or the specified message publishers in the topic.

Method

You can call the unsubscribeTopic method as follows:

virtual void unsubscribeTopic(const char* topic, const TopicOptions& options, uint64_t& requestId) = 0;
ParametersTypeRequiredDefaultDescription
topicconst char*Required-Topic name.
optionsconst TopicOptions&Required-Options for unsubscribe from a topic.
requestIduint64_t&Required-(Output) Request identifier. Use this parameter to identify and process the corresponding request.

The TopicOptions data type contains the following properties:

PropertiesTypeRequiredDefaultDescription
usersconst char**OptionalNULLA list of UserId of message publishers that you want to subscribe to. If you do not set this property, you can randomly subscribe to up to 64 users by default.
userCountsize_tOptional0User count.

Asynchronous callback

After calling this method, the SDK triggers the onUnsubscribeTopicResult callback and return the API execution result through the following parameters:

ParametersTypeDescription
requestIdconst uint64_tRequest identifier.
channelNameconst char*Channel name.
topicconst char*Topic name.
errorCodeRTM_ERROR_CODEError codes.

Basic usage

Example 1: Unsubscribe the specified message publisher in the topic

std::vector<const char*> users;
users.push_back("UserA");
users.push_back("UserB");

TopicOptions options;
options.users = users.data();
options.userCount = users.size();

uint64_t requestId;
streamChannel->unsubscribeTopic("topicName", options, requestId);

Example 2: Randomly unsubscribe 64 message publishers from the topic.

TopicOptions options;

uint64_t requestId;
streamChannel->unsubscribeTopic("topicName", options, requestId);
// Asynchronous callback
class RtmEventHandler : public IRtmEventHandler {
    void onUnsubscribeTopicResult(const uint64_t requestId, const char* channelName, const char* topic, RTM_ERROR_CODE errorCode) override {
        if (errorCode != RTM_ERROR_OK) {
            printf("UnsubscribeTopic failed error is %d reason is %s\n", errorCode, getErrorReason(errorCode));
        } else {
            printf("UnsubscribeTopic success\n");
        }
    }
};

Synchronous return value

  • 0: Success.
  • < 0: Failure.

getSubscribedUserList

Description

If you need to get the list of publishers that you subscribe to in a specific topic, you can call the getSubscribedUserList method.

Method

You can call the getSubscribedUserList method as follows:

virtual void getSubscribedUserList(const char* topic, uint64_t& requestId) = 0;
ParametersTypeRequiredDefaultDescription
topicconst char*Required-Topic name.
requestIduint64_t&Required-(Output) Request identifier. Use this parameter to identify and process the corresponding request.

Asynchronous callback

After calling this method, the SDK triggers the onGetSubscribedUserListResult callback and return the API execution result through the following parameters:

ParametersTypeDescription
requestIdconst uint64_tRequest identifier.
channelNameconst char*Channel name.
topicconst char*Topic name.
usersUserListUser array.
errorCodeRTM_ERROR_CODEError codes.

The UserList data type contains the following properties:

PropertiesTypeDescription
usersconst char**A list of UserId of message publishers that you subscribe to.
userCountsize_tPublisher count.

Basic usage

// Method call
uint64_t requestId;
streamChannel->getSubscribedUserList("topic", requestId);
// Asynchronous callback
class RtmEventHandler : public IRtmEventHandler {
    void onGetSubscribedUserListResult(const uint64_t requestId, const char* channelName, const char* topic, UserList users, RTM_ERROR_CODE errorCode) override {
        if (errorCode != RTM_ERROR_OK) {
            printf("getSubscribedUserList failed error is %d reason is %s\n", errorCode, getErrorReason(errorCode));
        } else {
            printf("getSubscribedUserList success\n");
            for (int i = 0 ;i < users.userCount; i++) {
                printf("user: %s\n", users.users[i]);
            }
        }
    }
};

Messages

Sending and receiving messages is the most basic function of the Signaling service. Any message sent by the Signaling server can be delivered to any online subscribing user within 100 ms. Depending on your business requirements, you can send messages to one user only or broadcast messages to multiple users.

Signaling offers 3 types of channels: message channels, user channels, and stream channels. These channel types have the following differences in how messages are transmitted and methods are called:

  • Message Channel: The real-time channel. Messages are transmitted through the channel, and the channel is highly scalable. Local users can call the publishTopicMessage method, set the channelType parameter to RTM_CHANNEL_TYPE_MESSAGE, and set the channelName parameter to the channel name to send messages in the channel. The remote users can call the subscribeTopic method to subscribe to the channel and receive messages.
  • User Channel: The real-time channel. Messages are transmitted to the specified user. Local users can call the publishTopicMessage method, set the channelType parameter to RTM_CHANNEL_TYPE_USER, and set the channelName parameter to the user ID to send messages to the specified user. The specified remote users receive messages through the onMessageEvent event notifications.
  • Stream Channel: The streaming transmission channel. Messages are transmitted through the topic. Users need to join a channel first, and then join a topic. Local users can call the publishTopicMessage method to send messages in the topic, and remote users can call the subscribeTopic method to subscribe to the topic and receive messages.

This page introduces how to send and receive messages in a message channel or a user channel.

IRtmClient Signaling client instance

publishTopicMessage

Description

You can directly call the publishTopicMessage method to send messages to all online users subscribed to this channel. Even if you do not subscribe to the channel, you can still send messages in the channel.

Information

The following practices can effectively improve the reliability of message transmission:
- The message payload should be within 32 KB; otherwise, the sending will fail.
- The upper limit of the rate at which messages are sent to a single channel is 60 QPS. If the sending rate exceeds the limit, some messages will be discarded. A lower rate is better, as long as the requirements are met.

After successfully calling this method, the SDK triggers a onMessageEvent event notification. Users who subscribe to the channel and enabled the event listener can receive this event notification. For details, see Event Listeners.

Method

You can call the publishTopicMessage method as follows:

virtual void publish(const char* channelName, const char* message, const size_t length, const PublishOptions& option, uint64_t& requestId) = 0;
ParametersTypeRequiredDefaultDescription
channelNameconst char*Required-Fill in a channel name to send messages in a specified channel, or fill in a user ID to send messages to a specified user.
messageconst char*Required-Message payload.
lengthconst size_tRequired-Length of message payload.
optionsconst PublishOptions&Required-Message options.
requestIduint64_t&Required-(Output) Request identifier. Use this parameter to identify and process the corresponding request.

The TopicMessageOptions data type contains the following properties:

PropertiesTypeRequiredDefaultDescription
channelTypeRTM_CHANNEL_TYPEOptionalRTM_CHANNEL_TYPE_MESSAGEChannel type. See RTM_CHANNEL_TYPE.
messageTypeRTM_MESSAGE_TYPEOptionalRTM_MESSAGE_TYPE_BINARYMessage type. See RTM_MESSAGE_TYPE.
customTypeconst char*OptionalNULLA user-defined field. Only supports string type.

Asynchronous callback

After calling this method, the SDK triggers the onPublishResult callback and return the API execution result through the following parameters:

ParametersTypeDescription
requestIdconst uint64_tRequest identifier.
errorCodeRTM_ERROR_CODEError codes.

Basic usage

Example 1: Send string messages to a specified channel.

PublishOptions options;
options.messageType = RTM_MESSAGE_TYPE_STRING;
options.customType = "PlainText";
options.channelTye = RTM_CHANNEL_TYPE_MESSAGE;
std::string message =  "hello world";
uint64_t requestId;
rtm_client->publish("channelName", message.c_str(), message.size(), options, requestId);

Example 2: Send byte messages to a specified channel.

PublishOptions options;
options.messageType = RTM_MESSAGE_TYPE_BINARY;
options.customType = "ByteArray";
options.channelTye = RTM_CHANNEL_TYPE_MESSAGE;

char message[5] = {0x00, 0x01, 0x02, 0x03, 0x04};

uint64_t requestId;
rtmClient->publish("channelName", message, 5, options, requestId);

Example 3: Send string messages to a specified user.

PublishOptions options;
options.messageType = RTM_MESSAGE_TYPE_STRING;
options.customType = "PlainText";
options.channelTye = RTM_CHANNEL_TYPE_USER;
std::string message =  "hello world";
uint64_t requestId;
rtm_client->publish("channelName", message.c_str(), message.size(), options, requestId);

Example 4: Send byte messages to a specified user.

PublishOptions options;
options.messageType = RTM_MESSAGE_TYPE_BINARY;
options.customType = "ByteArray";
options.channelTye = RTM_CHANNEL_TYPE_USER;

char message[5] = {0x00, 0x01, 0x02, 0x03, 0x04};

uint64_t requestId;
rtmClient->publish("channelName", message, 5, options, requestId);

Example 5: Asynchronous callback.

class RtmEventHandler : public IRtmEventHandler {
    void onPublishResult(const uint64_t requestId, RTM_ERROR_CODE errorCode) override {
        if (errorCode != RTM_ERROR_OK) {
          printf("publish message failed error is %d reason is %s\n", errorCode, getErrorReason(errorCode));
        } else {
            printf("publish message success\n");
        }
    }
};

Receive

Signaling provides event notifications for messages, states, and event changes. By listening for callbacks, you can receive messages and events within subscribed channels. As an example, the code snippet below shows how to receive messages from the user channel:

class RtmEventHandler : public IRtmEventHandler {
    void onMessageEvent(const MessageEvent& event) override {
 // User Channel Message
        if (event.channelType == RTM_CHANNEL_TYPE_USER) {
          printf("receive message from %s, message: %s\n", event.publisher, event.message);
        }
    }

 // ...
};

For information on how to add and set event listeners, see Event Listeners.

Presence

The presence feature provides the ability to monitor user online, offline, and user historical state change. With the Presence feature, you can get real-time access to the following information:

  • Real-time event notification when a user joins or leaves a specified channel.
  • Real-time event notification when the custom temporary user state changes.
  • Query which channels a specified user has joined or subscribed to.
  • Query which users have joined a specified channel and their temporary user state data.

Information

Presence applies to both message channels and stream channels.

IRtmPresence Presence instance

getOnlineUsers

Description

By calling the getOnlineUsers method, you can query real-time information about the number of online users, the list of online users, and the temporary state of online users in a specified channel.

Method

You can call the getOnlineUsers method as follows:

virtual void getOnlineUsers(const char* channelName, RTM_CHANNEL_TYPE channelType, const PresenceOptions& options, uint64_t& requestId) = 0;
ParametersTypeRequiredDefaultDescription
channelNameconst char*Required-Channel name.
channelTypeRTM_CHANNEL_TYPERequired-Channel types. See RTM_CHANNEL_TYPE.
optionsconst PresenceOptions&Required-Query options.
requestIduint64_t&Required-(Output) Request identifier. Use this parameter to identify and process the corresponding request.

The PresenceOptions data type contains the following properties:

PropertiesTypeRequiredDefaultDescription
includeUserIdboolOptionaltrueWhether the returned result includes the user ID of online members.
includeStateboolOptionalfalseWhether the returned result includes temporary state data of online users.
pageconst char*OptionalNULLPage number of the returned result. If you do not provide this property, the SDK returns the first page by default. You can check whether there is next page in the returned result.

Asynchronous callback

After calling this method, the SDK triggers the onGetOnlineUsersResult callback and return the API execution result through the following parameters:

ParametersTypeDescription
requestIdconst uint64_tRequest identifier.
userStateListconst UserState*List of online users and their temporary state information in a specified channel.
countconst size_tThe list length of UserStateList. When you set both includeUserId and includeState properties in the getOnlineUsers method to false, this value represents the total number of current online users in the channel.
nextPageconst char*Page number of the next page. Confirm whether there is a next page:
- A null value indicates that next page does not exist.
- A non-null value indicates that there is a next page. You can fill this value in the page property of the getOnlineUsers method to query the next page results.
errorCodeRTM_ERROR_CODEError codes.

The UserState data type contains the following properties:

PropertiesTypeDescription
userIdconst char*User ID.
statesconst StateItem*List of online users and their temporary state information in a specified channel.
statesCountsize_tState count.

StateItem data type contains the following properties:

PropertiesTypeDescription
keyconst char*Key of the user state. If the specified key already exists, the SDK overwrites the value; if the specified key does not exist, the SDK creates the key-value pair.
valueconst char*Value of the user state.

Basic usage

// Method call
PresenceOptions options;
options.includeState = true;
options.includeUserId =true;
options.page = "yourBookMark";
uint64_t requestId;
rtmClient->getPresence()->getOnlineUsers("channelName", RTM_CHANNEL_TYPE_MESSAGE, options, requestId);
// Asynchronous callback
class RtmEventHandler : public IRtmEventHandler {
    void onGetOnlineUsersResult(const uint64_t requestId, const UserState *userStateList, const size_t count, const char *nextPage, RTM_ERROR_CODE errorCode) override {
        if (errorCode != RTM_ERROR_OK) {
            printf("get online users failed error is %d reason is %s\n", errorCode, getErrorReason(errorCode));
        } else {
            printf("get online users success\n");
            for (int i = 0; i < count; i++) {
                printf("user: %s\n", userStateList[i].userId);
                for (int j = 0; j < userStateList[i].statesCount; j++) {
                    printf("key: %s value: %s\n", userStateList[i].states[j].key, userStateList[i].states[j].value);
                }
            }
        }
    }
};

getUserChannels

Description

In use-cases such as statistic analytics and debugging, you may need to know all the channels that a specified user has subscribed to or joined. Call the getUserChannels method to get the list of channels where the specified user is in real time.

Method

You can call the getUserChannels method as follows:

virtual void getUserChannels(const char* userId, uint64_t& requestId) = 0;
ParametersTypeRequiredDefaultDescription
userIdconst char*Required-User ID.
requestIduint64_t&Required-(Output) Request identifier. Use this parameter to identify and process the corresponding request.

Asynchronous callback

After calling this method, the SDK triggers the onGetUserChannelsResult callback and return the API execution result through the following parameters:

ParametersTypeDescription
requestIdconst uint64_tRequest identifier.
channelsconst ChannelInfo*Channel information.
countconst size_tChannel count.
errorCodeRTM_ERROR_CODEError codes.

ChannelInfo data type contains the following properties:

PropertiesTypeDescription
channelNameconst char*Channel name.
channelTypeRTM_CHANNEL_TYPEChannel types. See RTM_CHANNEL_TYPE.

Basic usage

// Method call
uint64_t requestId;
rtmClient->getPresence()->getUserChannels("tony", requestId);
// Asynchronous callback
class RtmEventHandler : public IRtmEventHandler {
    void onGetUserChannelsResult(const uint64_t requestId, const ChannelInfo *channels, const size_t count, RTM_ERROR_CODE errorCode) override {
        if (errorCode != RTM_ERROR_OK) {
            printf("get user channels failed error is %d reason is %s\n", errorCode, getErrorReason(errorCode));
        } else {
            printf("get user channels success\n");
            for (int i = 0; i < count; i++) {
                printf("channel: %s channel type: %d\n", channels[i].channelName, channels[i].channelType);
            }
        }
    }
};

setState

Description

To meet different requirements in different business use-cases for setting user states, Signaling provides the setState method to customize the temporary user state. Users can add custom states such as scores, game state, location, mood, and hosting state for themselves.

After successful setup, as long as the user keeps subscribing to the channel and stays online, the custom states can persist in the channel. setState method sets the temporary user state, and the state disappears when the user leaves the channel or disconnects from Signaling. If you need to restore user states when rejoining a channel or reconnecting, you need to cache the data locally in real time. If you want to permanently save user states, Agora recommends you use the setUserMetadata method of the storage function instead.

If a user modifies the temporary user state, Signaling triggers the RTM_PRESENCE_EVENT_TYPE_REMOTE_STATE_CHANGED type of the onPresenceEvent event in real time. You can receive the event by subscribing to the channel and configuring the corresponding property.

Method

You can call the setState method as follows:

virtual void setState(const char* channelName, RTM_CHANNEL_TYPE channelType, const StateItem* items, size_t count, uint64_t& requestId) = 0;
ParametersTypeRequiredDefaultDescription
channelNameconst char*Required-Channel name
channelTypeRTM_CHANNEL_TYPERequired-Channel types. See RTM_CHANNEL_TYPE.
itemsconst StateItem*Required-User state.
countsize_tRequired-Count of the user state.
requestIduint64_t&Required-(Output) Request identifier. Use this parameter to identify and process the corresponding request.

StateItem data type contains the following properties:

PropertiesTypeDescription
keyconst char*Key of the user state. If the specified key already exists, the SDK overwrites the value; if the specified key does not exist, the SDK creates the key-value pair.
valueconst char*Value of the user state.

Asynchronous callback

After calling this method, the SDK triggers the onPresenceSetStateResult callback and return the API execution result through the following parameters:

ParametersTypeDescription
requestIdconst uint64_tRequest identifier.
errorCodeRTM_ERROR_CODEError codes.

Basic usage

// Method call
std::vector<StateItem> items;
StateItem item;
item.key = "mood";
item.value = "pumped";
items.push_back(item);

uint64_t requestId;
rtmClient->getPresence()->setState("channelName", RTM_CHANNEL_TYPE_MESSAGE, items.data(), items.size(), requestId);
// Asynchronous callback
class RtmEventHandler : public IRtmEventHandler {
    void onPresenceSetStateResult(const uint64_t requestId, RTM_ERROR_CODE errorCode) override {
        if (errorCode != RTM_ERROR_OK) {
            printf("SetState failed error is %d reason is %s\n", errorCode, getErrorReason(errorCode));
        } else {
            printf("SetState success\n");
        }
    }
};

getState

Description

To get the temporary user state of a specified user in the channel, you can use the getState method.

Method

You can call the getState method as follows:

virtual void getState(const char* channelName, RTM_CHANNEL_TYPE channelType, const char* userId, uint64_t& requestId) = 0;
ParametersTypeRequiredDefaultDescription
channelNameconst char*Required-Channel name.
channelTypeRTM_CHANNEL_TYPERequired-Channel types. See RTM_CHANNEL_TYPE.
userIdconst char*Required-User ID.
requestIduint64_t&Required-(Output) Request identifier. Use this parameter to identify and process the corresponding request.

Asynchronous callback

After calling this method, the SDK triggers the onPresenceGetStateResult callback and return the API execution result through the following parameters:

ParametersTypeDescription
requestIdconst uint64_tRequest identifier.
statesconst UserState&List of online users and their temporary state information in a specified channel.
errorCodeRTM_ERROR_CODEError codes.

The UserState data type contains the following properties:

PropertiesTypeDescription
userIdconst char*User ID.
statesconst StateItem*List of online users and their temporary state information in a specified channel.
statesCountsize_tState count.

StateItem data type contains the following properties:

PropertiesTypeDescription
keyconst char*Key of the user state. If the specified key already exists, the SDK overwrites the value; if the specified key does not exist, the SDK creates the key-value pair.
valueconst char*Value of the user state.

Basic usage

// Method call
uint64_t requestId;
rtmClient->getPresence()->getState("channelName", RTM_CHANNEL_TYPE_MESSAGE, "tony", requestId);
// Asynchronous callback
class RtmEventHandler : public IRtmEventHandler {
    void onPresenceGetStateResult(const uint64_t requestId, const UserState &state, RTM_ERROR_CODE errorCode) override {
        if (errorCode != RTM_ERROR_OK) {
            printf("GetState failed error is %d reason is %s\n", errorCode, getErrorReason(errorCode));
        } else {
            printf("GetState user id: %s success\n", state.userId);
            for (int i = 0; i < state.statesCount; i++) {
                printf("key: %s, value: %s\n", state.states[i].key, state.states[i].value);
            }
        }
    }
};

removeState

Description

When a temporary user state is no longer needed, you can call the removeState method to remove one or more of your temporary states.

When the user state is removed, the user who has subscribed to the channel and enabled the presence event listener receives the RTM_PRESENCE_EVENT_TYPE_REMOTE_STATE_CHANGED type of onPresenceEvent event notification. See Event Listeners.

Method

You can call the removeState method as follows:

virtual void removeState(const char* channelName, RTM_CHANNEL_TYPE channelType, const char** keys, size_t count, uint64_t& requestId) = 0;
ParametersTypeRequiredDefaultDescription
channelNameconst char*Required-Channel name
channelTypeRTM_CHANNEL_TYPERequired-Channel types. See RTM_CHANNEL_TYPE.
keysconst char**Required-List of keys to be deleted. If you do not provide this property, the SDK removes all states.
countsize_tRequired-Key count.
requestIduint64_t&Required-(Output) Request identifier. Use this parameter to identify and process the corresponding request.

Asynchronous callback

After calling this method, the SDK triggers the onPresenceRemoveStateResult callback and return the API execution result through the following parameters:

ParametersTypeDescription
requestIdconst uint64_tRequest identifier.
errorCodeRTM_ERROR_CODEError codes.

Basic usage

// Method call
std::vector<const char*> keys;
keys.push_back("key0");
keys.push_back("key1");
keys.push_back("key2");

uint64_t requestId;
rtmClient->getPresence()->removeState("channelName", RTM_CHANNEL_TYPE_MESSAGE, keys.data(), keys.size(), requestId);
// Asynchronous callback
class RtmEventHandler : public IRtmEventHandler {
    void onPresenceRemoveStateResult(const uint64_t requestId, RTM_ERROR_CODE errorCode) override {
        if (errorCode != RTM_ERROR_OK) {
            printf("RemoveState failed error is %d reason is %s\n", errorCode, getErrorReason(errorCode));
        } else {
            printf("RemoveState success\n");
        }
    }
};

Storage

The storage feature provides a dynamic database mechanism that allows developers to dynamically set, store, update, and delete data such as channel metadata and user metadata.

IRtmStorage Storage instance

setChannelMetadata

Description

The setChannelMetadata method sets metadata for a message channel or stream channel. A channel can only have one set of metadata, but each set of metadata can have one or more metadata items. If you call this method multiple times, the SDK retrieves the key of the metadata items in turn and apply settings according to the following rules:

  • If you set metadata with different key, the SDK adds each set of metadata in sequence according to the order of the method calls.
  • If you set metadata with the same key, the value of the last setting overwrites the previous one.

Channel metadata also introduces the version control logic CAS (Compare And Set). This method provides two independent version control fields, and you can set one or more of them according to your actual business use-case:

  • Enable version number verification for the entire set of channel metadata by setting the majorRevision property in the Metadata data type.
  • Enable version number verification for a single metadata item by setting the revision property in the MetadataItem class.

When setting channel metadata or metadata items, you can control whether to enable version number verification by specifying the revision property:

  • The default value of the revision property is -1, indicating that this method call does not perform any CAS verification. If the channel metadata or metadata item already exists, the latest value overwrites the previous one. If the channel metadata or metadata item does not exist, the SDK creates it.
  • If the revision property is a positive integer, this method call performs the CAS verification. If the channel metadata or metadata item already exists, the SDK updates the corresponding value after the version number verification succeeds. If the channel metadata or metadata item does not exist, the SDK returns the error code.

After successfully setting channel metadata, users who subscribe to the channel and enable event listeners can receive the RTM_STORAGE_TYPE_CHANNEL type of the onStorageEvent event notification. See Event listeners.

Method

You can call the setChannelMetadata method as follows:

virtual void setChannelMetadata(
    const char* channelName, RTM_CHANNEL_TYPE channelType,
    const Metadata& data, const MetadataOptions& options,
    const char* lockName, uint64_t& requestId) = 0;
ParametersTypeRequiredDefaultDescription
channelNameconst char*Required-Channel name.
channelTypeRTM_CHANNEL_TYPERequired-Channel types. See RTM_CHANNEL_TYPE.
dataconst Metadata&Required-Metadata item. See Metadata.
optionsconst MetadataOptions&Required-Options for setting the channel metadata.
lockNameconst char*Required-Lock name. If set, only users who call the acquireLock method to acquire the lock can perform operations.
requestIduint64_t&Required-(Output) Request identifier. Use this parameter to identify and process the corresponding request.

The MetadataOptions data type contains the following properties:

PropertiesTypeRequiredDefaultDescription
recordTsboolOptionalfalseWhether to record the timestamp of the edits.
recordUserIdboolOptionalfalseWhether to record the user ID of the editor.

Asynchronous callback

After calling this method, the SDK triggers the onSetChannelMetadataResult callback and return the API execution result through the following parameters:

ParametersTypeDescription
requestIdconst uint64_tRequest identifier.
channelNameconst char*Channel name.
channelTypeRTM_CHANNEL_TYPEChannel type. See RTM_CHANNEL_TYPE.
errorCodeRTM_ERROR_CODEError codes.

Basic usage

// Method call
Metadata metadata;
metadata.majorRevision = 174298270;
std::vector<agora::rtm::MetadataItem> items;
items.emplace_back(MetadataItem("Apple", "100", 174298200));
items.emplace_back(MetadataItem("Banana", "200", 174298100));
metadata.items = items.data();
metadata.itemCount = items.size();
MetadataOptions options;
options.recordTs = true;
options.recordUserId = true;
uint64_t requestId;
rtmClient->getStorage()->setChannelMetadata("channelName", RTM_CHANNEL_TYPE_MESSAGE, metadata, options, "lockName", requestId);
// Asynchronous callback
class RtmEventHandler : public IRtmEventHandler {
    void onSetChannelMetadataResult(const uint64_t requestId, const char *channelName, RTM_CHANNEL_TYPE channelType, RTM_ERROR_CODE errorCode) override {
        if (errorCode != RTM_ERROR_OK) {
            printf("SetChannelMetadata failed error is %d reason is %s\n", errorCode, getErrorReason(errorCode));
        } else {
            printf("SetChannelMetadata success\n");
        }
    }
};

getChannelMetadata

Description

The getChannelMetadata method can get the metadata of the specified channel.

Method

You can call the getChannelMetadata method as follows:

virtual void getChannelMetadata(
    const char* channelName, RTM_CHANNEL_TYPE channelType, uint64_t& requestId) = 0;
ParametersTypeRequiredDefaultDescription
channelNameconst char*Required-Channel name.
channelTypeRTM_CHANNEL_TYPERequired-Channel types. See RTM_CHANNEL_TYPE.
requestIduint64_t&Required-(Output) Request identifier. Use this parameter to identify and process the corresponding request.

Asynchronous callback

After calling this method, the SDK triggers the onGetChannelMetadataResult callback and return the API execution result through the following parameters:

ParametersTypeDescription
requestIdconst uint64_tRequest identifier.
channelNameconst char*Channel name.
channelTypeRTM_CHANNEL_TYPEChannel type. See RTM_CHANNEL_TYPE.
dataconst Metadata&Metadata item. See Metadata.
errorCodeRTM_ERROR_CODEError codes.

Basic usage

// Method call
uint64_t requestId;
rtmClient->getStorage()->getChannelMetadata("channelName", RTM_CHANNEL_TYPE_MESSAGE, requestId);
// Asynchronous callback
class RtmEventHandler : public IRtmEventHandler {
    void onGetChannelMetadataResult(const uint64_t requestId, const char *channelName, RTM_CHANNEL_TYPE channelType, const Metadata& data, RTM_ERROR_CODE errorCode) override {
        if (errorCode != RTM_ERROR_OK) {
            printf("GetChannelMetadata failed error is %d reason is %s\n", errorCode, getErrorReason(errorCode));
        } else {
            printf("GetChannelMetadata success %d channel: %s, channel type: %d\n");
            for (int i = 0 ; i < data.itemCount; i++) {
                printf("key: %s value: %s revision: %lld\n", data.items[i].key, data.items[i].value, data.items[i].revision);
            }
        }
    }
};

removeChannelMetadata

Description

The removeChannelMetadata method can remove channel metadata or metadata items.

When removing channel metadata or metadata items, you can control whether to enable version number verification by specifying the revision property:

  • The default value of the revision property is -1, indicating that this method call does not perform any CAS verification. If the channel metadata or metadata item already exists, the SDK removes it. If the channel metadata or metadata item does not exist, the SDK returns the error code.
  • If the revision property is a positive integer, this method call performs the CAS verification. If the channel metadata or metadata item already exists, the SDK removes the corresponding value after the version number verification succeeds. If the channel metadata or metadata item does not exist, the SDK returns the error code.

After successfully removing channel metadata or metadata items, users who subscribe to the channel and enable event listeners can receive the RTM_STORAGE_TYPE_CHANNEL type of the onStorageEvent event notification. See Event listeners.

Method

You can call the removeChannelMetadata method as follows:

virtual void removeChannelMetadata(
    const char* channelName, RTM_CHANNEL_TYPE channelType,
    const Metadata& data, const MetadataOptions& options,
    const char* lockName, uint64_t& requestId) = 0;
ParametersTypeRequiredDefaultDescription
channelNameconst char*Required-Channel name.
channelTypeRTM_CHANNEL_TYPERequired-Channel types. See RTM_CHANNEL_TYPE.
dataconst Metadata&Required-Metadata item. See Metadata.
optionsconst MetadataOptions&Required-Options for setting the channel metadata.
lockNameconst char*Required-Lock name. If set, only users who call the acquireLock method to acquire the lock can perform operations.
requestIduint64_t&Required-(Output) Request identifier. Use this parameter to identify and process the corresponding request.

The MetadataOptions data type contains the following properties:

PropertiesTypeRequiredDefaultDescription
recordTsboolOptionalfalseWhether to record the timestamp of the edits.
recordUserIdboolOptionalfalseWhether to record the user ID of the editor.

Asynchronous callback

After calling this method, the SDK triggers the onRemoveChannelMetadataResult callback and return the API execution result through the following parameters:

ParametersTypeDescription
requestIdconst uint64_tRequest identifier.
channelNameconst char*Channel name.
channelTypeRTM_CHANNEL_TYPEChannel type. See RTM_CHANNEL_TYPE.
errorCodeRTM_ERROR_CODEError codes.

Basic usage

// Method call
Metadata metadata;
metadata.majorRevision = 174298270;
std::vector<agora::rtm::MetadataItem> items;
items.emplace_back(MetadataItem("Apple", "", 174298200));
metadata.items = items.data();
metadata.itemCount = items.size();

MetadataOptions options;
options.recordTs = true;
options.recordUserId = true;

uint64_t requestId;
rtmClient->getStorage()->removeChannelMetadata("channelName", RTM_CHANNEL_TYPE_MESSAGE, metadata, options, "lockName", requestId);
// Asynchronous callback
class RtmEventHandler : public IRtmEventHandler {
    void onRemoveChannelMetadataResult(const uint64_t requestId, const char *channelName, RTM_CHANNEL_TYPE channelType, RTM_ERROR_CODE errorCode) override {
        if (errorCode != RTM_ERROR_OK) {
            printf("RemoveChannelMetadata failed error is %d reason is %s\n", errorCode, getErrorReason(errorCode));
        } else {
            printf("RemoveChannelMetadata success\n");
        }
    }
};

updateChannelMetadata

Description

The updateChannelMetadata method can update existing channel metadata. Each time you call this method, you can update one channel metadata or a channel metadata item.

After successfully updating channel metadata, users who subscribe to the channel and enable event listeners can receive the RTM_STORAGE_TYPE_CHANNEL type of the onStorageEvent event notification. See Event listeners.

Information

You cannot use this method to update metadata items which do not exist.

Method

You can call the updateChannelMetadata method as follows:

virtual void updateChannelMetadata(
    const char* channelName, RTM_CHANNEL_TYPE channelType,
    const Metadata& data, const MetadataOptions& options,
    const char* lockName, uint64_t& requestId) = 0;
ParametersTypeRequiredDefaultDescription
channelNameconst char*Required-Channel name.
channelTypeRTM_CHANNEL_TYPERequired-Channel types. See RTM_CHANNEL_TYPE.
dataconst Metadata&Required-Metadata item. See Metadata.
optionsconst MetadataOptions&Required-Options for setting the channel metadata.
lockNameconst char*Required-Lock name. If set, only users who call the acquireLock method to acquire the lock can perform operations.
requestIduint64_t&Required-(Output) Request identifier. Use this parameter to identify and process the corresponding request.

The MetadataOptions data type contains the following properties:

PropertiesTypeRequiredDefaultDescription
recordTsboolOptionalfalseWhether to record the timestamp of the edits.
recordUserIdboolOptionalfalseWhether to record the user ID of the editor.

Asynchronous callback

After calling this method, the SDK triggers the onUpdateChannelMetadataResult callback and return the API execution result through the following parameters:

ParametersTypeDescription
requestIdconst uint64_tRequest identifier.
channelNameconst char*Channel name.
channelTypeRTM_CHANNEL_TYPEChannel type. See RTM_CHANNEL_TYPE.
errorCodeRTM_ERROR_CODEError codes.

Basic usage

// Method call
Metadata metadata;
metadata.majorRevision = 174298270;
std::vector<agora::rtm::MetadataItem> items;
items.emplace_back(MetadataItem("Apple", "120", 174298200));
metadata.items = items.data();
metadata.itemCount = items.size();

MetadataOptions options;
options.recordTs = true;
options.recordUserId = true;

uint64_t requestId;
rtmClient->getStorage()->updateChannelMetadata("channelName", RTM_CHANNEL_TYPE_MESSAGE, metadata, options, "lockName", requestId);
// Asynchronous callback
class RtmEventHandler : public IRtmEventHandler {
    void onUpdateChannelMetadataResult(const uint64_t requestId, const char *channelName, RTM_CHANNEL_TYPE channelType, RTM_ERROR_CODE errorCode) override {
        if (errorCode != RTM_ERROR_OK) {
            printf("UpdateChannelMetadata failed error is %d reason is %s\n", errorCode, getErrorReason(errorCode));
        } else {
            printf("UpdateChannelMetadata success\n");
        }
    }
};

setUserMetadata

Description

The setUserMetadata method can set metadata for a user. If you call this method multiple times, the SDK retrieves the key of the metadata items in turn and apply settings according to the following rules:

  • If you set metadata with different key, the SDK adds each set of metadata in sequence according to the order of the method calls.
  • If you set metadata with the same key, the value of the last setting overwrites the previous one.

After successfully setting user metadata, users who subscribe to the user and enable event listeners can receive the RTM_STORAGE_TYPE_USER type of the onStorageEvent event notification. See Event listeners.

User metadata also introduces the version control logic CAS (Compare And Set). This method provides two independent version control fields, and you can set one or more of them according to your actual business use-case:

  • Enable version number verification for the entire set of channel metadata by setting the majorRevision property in the Metadata data type.
  • Enable version number verification for a single metadata item by setting the revision property in the MetadataItem class.

When setting user metadata or metadata items, you can control whether to enable version number verification by specifying the revision property:

  • The default value of the revision property is -1, indicating that this method call does not perform any CAS verification. If the user metadata or metadata item already exists, the latest value overwrites the previous one. If the user metadata or metadata item does not exist, the SDK creates it.
  • If the revision property is a positive integer, this method call performs the CAS verification. If the user metadata or metadata item already exists, the SDK updates the corresponding value after the version number verification succeeds. If the user metadata or metadata item does not exist, the SDK returns the error code.

After successfully setting user metadata, users who subscribe to the user and enable event listeners can receive the RTM_STORAGE_TYPE_USER type of the onStorageEvent event notification. See Event listeners.

Method

You can call the setUserMetadata method as follows:

virtual void setUserMetadata(
    const char* userId, const Metadata& data,
    const MetadataOptions& options, uint64_t& requestId) = 0;
ParametersTypeRequiredDefaultDescription
userIdconst char*Required-User ID.
dataconst Metadata&Required-Metadata item. See Metadata.
optionsconst MetadataOptions&Required-Options for setting the channel metadata.
requestIduint64_t&Required-(Output) Request identifier. Use this parameter to identify and process the corresponding request.

The MetadataOptions data type contains the following properties:

PropertiesTypeRequiredDefaultDescription
recordTsboolOptionalfalseWhether to record the timestamp of the edits.
recordUserIdboolOptionalfalseWhether to record the user ID of the editor.

Asynchronous callback

After calling this method, the SDK triggers the onSetUserMetadataResult callback and return the API execution result through the following parameters:

ParametersTypeDescription
requestIdconst uint64_tRequest identifier.
userIdconst char*User ID.
errorCodeRTM_ERROR_CODEError codes.

Basic usage

// Method call
Metadata metadata;
metadata.majorRevision = 174298270;
std::vector<agora::rtm::MetadataItem> items;
items.emplace_back(MetadataItem("Name", "Tony", 174298200));
items.emplace_back(MetadataItem("Mute", "true", 174298100));
metadata.items = items.data();
metadata.items = items.size();

MetadataOptions options;
options.recordTs = true;
options.recordUserId = true;

uint64_t requestId;
rtmClient->getStorage()->setUserMetadata("Tony", metadata, options, requestId);
// Asynchronous callback
class RtmEventHandler : public IRtmEventHandler {
    void onSetUserMetadataResult(const uint64_t requestId, const char *userId, RTM_ERROR_CODE errorCode) override {
        if (errorCode != RTM_ERROR_OK) {
            printf("SetUserMetadata failed error is %d reason is %s\n", errorCode, getErrorReason(errorCode));
        } else {
            printf("SetUserMetadata success\n");
        }
    }
};

getUserMetadata

Description

The getUserMetadata method can get the metadata and metadata item for the specified user.

Method

You can call the getUserMetadata method as follows:

virtual void getUserMetadata(const char* userId, uint64_t& requestId) = 0;
ParametersTypeRequiredDefaultDescription
userIdconst char*Required-User ID.
requestIduint64_t&Required-(Output) Request identifier. Use this parameter to identify and process the corresponding request.

Asynchronous callback

After calling this method, the SDK triggers the onGetUserMetadataResult callback and return the API execution result through the following parameters:

ParametersTypeDescription
requestIdconst uint64_tRequest identifier.
userIdconst char*User ID.
dataconst Metadata&Metadata item. See Metadata.
errorCodeRTM_ERROR_CODEError codes.

Basic usage

// Method call
uint64_t requestId;
rtmClient->getStorage()->getUserMetadata("Tony", requestId);
// Asynchronous callback
class RtmEventHandler : public IRtmEventHandler {
    void onGetUserMetadataResult(const uint64_t requestId, const char *userId, const Metadata& data, RTM_ERROR_CODE errorCode) override {
        if (errorCode != RTM_ERROR_OK) {
            printf("GetUserMetadata failed error is %d reason is %s\n", errorCode, getErrorReason(errorCode));
        } else {
            printf("GetUserMetadata success user id: %s\n", userId);
            for (int i = 0 ; i < data.itemCount; i++) {
                printf("key: %s value: %s revision: %lld\n", data.items[i].key, data.items[i].value, data.items[i].revision);
            }
        }
    }
};

removeUserMetadata

Description

The removeUserMetadata method can remove user metadata or metadata items.

After successfully removing user metadata, users who subscribe to the user and enable event listeners can receive the RTM_STORAGE_TYPE_USER type of the onStorageEvent event notification. See Event listeners.

Method

You can call the removeUserMetadata method as follows:

virtual void removeUserMetadata(
    const char* userId, const Metadata& data,
    const MetadataOptions& options, uint64_t& requestId) = 0;
ParametersTypeRequiredDefaultDescription
userIdconst char*Required-User ID.
dataconst Metadata&Required-Metadata item. See Metadata.
optionsconst MetadataOptions&Required-Options for setting the channel metadata.
requestIduint64_t&Required-(Output) Request identifier. Use this parameter to identify and process the corresponding request.

The MetadataOptions data type contains the following properties:

PropertiesTypeRequiredDefaultDescription
recordTsboolOptionalfalseWhether to record the timestamp of the edits.
recordUserIdboolOptionalfalseWhether to record the user ID of the editor.

Asynchronous callback

After calling this method, the SDK triggers the onRemoveUserMetadataResult callback and return the API execution result through the following parameters:

ParametersTypeDescription
requestIdconst uint64_tRequest identifier.
userIdconst char*User ID.
errorCodeRTM_ERROR_CODEError codes.

Basic usage

// Method call
Metadata metadata;
metadata.majorRevision = 174298270;
std::vector<MetadataItem> items;
MetadataItem item;
item.key = "Mute";
item.revision = 174298200;
items.emplace_back(item);
metadata.items = items.data();
metadata.itemCount = items.size();

uint64_t requestId;
rtmClient->getStorage()->removeUserMetadata("Tony", metadata, MetadataOptions(), requestId);
// Asynchronous callback
class RtmEventHandler : public IRtmEventHandler {
    void onRemoveUserMetadataResult(const uint64_t requestId, const char *userId, RTM_ERROR_CODE errorCode) override {
        if (errorCode != RTM_ERROR_OK) {
            printf("RemoveUserMetadata failed error is %d reason is %s\n", errorCode, getErrorReason(errorCode));
        } else {
            printf("RemoveUserMetadata success\n");
        }
    }
};

updateUserMetadata

Description

The updateUserMetadata method can update existing user metadata.

After successfully updating channel metadata, users who subscribe to the user and enable event listeners can receive the RTM_STORAGE_TYPE_USER type of the onStorageEvent event notification. See Event listeners.

Information

You cannot use this method to update metadata items which do not exist.

Method

You can call the updateUserMetadata method as follows:

virtual void updateUserMetadata(
    const char* userId, const Metadata& data,
    const MetadataOptions& options, uint64_t& requestId) = 0;
ParametersTypeRequiredDefaultDescription
userIdconst char*Required-User ID.
dataconst Metadata&Required-Metadata item. See Metadata.
optionsconst MetadataOptions&Required-Options for setting the channel metadata.
requestIduint64_t&Required-(Output) Request identifier. Use this parameter to identify and process the corresponding request.

The MetadataOptions data type contains the following properties:

PropertiesTypeRequiredDefaultDescription
recordTsboolOptionalfalseWhether to record the timestamp of the edits.
recordUserIdboolOptionalfalseWhether to record the user ID of the editor.

Asynchronous callback

After calling this method, the SDK triggers the onUpdateUserMetadataResult callback and return the API execution result through the following parameters:

ParametersTypeDescription
requestIdconst uint64_tRequest identifier.
userIdconst char*User ID.
errorCodeRTM_ERROR_CODEError codes.

Basic usage

// Method call
Metadata metadata;
metadata.majorRevision = 174298270;
std::vector<MetadataItem> items;
items.emplace_back(MetadataItem("Apple", "100", 174298200));
metadata.items = items.data();
metadata.itemCount = items.size();

MetadataOptions options;
options.recordTs = true;
options.recordUserId = true;

uint64_t requestId;
rtmClient->getStorage()->updateUserMetadata("Tony", metadata, options, requestId);
// Asynchronous callback
class RtmEventHandler : public IRtmEventHandler {
    void onUpdateUserMetadataResult(const uint64_t requestId, const char *userId, RTM_ERROR_CODE errorCode) override {
        if (errorCode != RTM_ERROR_OK) {
            printf("UpdateUserMetadata failed error is %d reason is %s\n", errorCode, getErrorReason(errorCode));
        } else {
            printf("UpdateUserMetadata success\n");
        }
    }
};

subscribeUserMetadata

Description

The subscribeUserMetadata method can subscribe to metadata for a specified user.

After successfully subscribing to the user metadata, you can receive the RTM_STORAGE_TYPE_USER type of the onStorageEvent event notification when the metadata for that user changes. See Event listeners.

Method

You can call the subscribeUserMetadata method as follows:

virtual void subscribeUserMetadata(const char* userId, uint64_t& requestId) = 0;
ParametersTypeRequiredDefaultDescription
userIdconst char*Required-User ID.
requestIduint64_t&Required-(Output) Request identifier. Use this parameter to identify and process the corresponding request.

Asynchronous callback

After calling this method, the SDK triggers the onUpdateUserMetadataResult callback and return the API execution result through the following parameters:

ParametersTypeDescription
requestIdconst uint64_tRequest identifier.
userIdconst char*User ID.
errorCodeRTM_ERROR_CODEError codes.

Basic usage

// Method call
uint64_t requestId;
rtmClient->getStorage()->subscribeUserMetadata("Tony", requestId);
// Asynchronous callback
class RtmEventHandler : public IRtmEventHandler {
    void onSubscribeUserMetadataResult(const uint64_t requestId, const char *userId, RTM_ERROR_CODE errorCode) override {
        if (errorCode != RTM_ERROR_OK) {
            printf("SubscribeUserMetadata failed error is %d reason is %s\n", errorCode, getErrorReason(errorCode));
        } else {
            printf("SubscribeUserMetadata success\n");
        }
    }
};

unsubscribeUserMetadata

Description

If you do not need to receive notifications of changes to a user metadata, call the unsubscribeUserMetadata method to unsubscribe.

Method

You can call the unsubscribeUserMetadata method as follows:

virtual void unsubscribeUserMetadata(const char* userId, uint64_t& requestId) = 0;
ParametersTypeRequiredDefaultDescription
userIdconst char*Required-User ID.
requestIduint64_t&Required-(Output) Request identifier. Use this parameter to identify and process the corresponding request.

Asynchronous callback

After calling this method, the SDK triggers the onUnsubscribeUserMetadataResult callback and return the API execution result through the following parameters:

ParametersTypeDescription
requestIdconst uint64_tRequest identifier.
userIdconst char*User ID.
errorCodeRTM_ERROR_CODEError codes.

Basic usage

uint64_t requestId;
rtm_client->getStorage()->unsubscribeUserMetadata("Tony", requestId);
// Asynchronous callback
class RtmEventHandler : public IRtmEventHandler {
    void onUnsubscribeUserMetadataResult(const uint64_t requestId, const char* userId, RTM_ERROR_CODE errorCode) override {
        if (errorCode != RTM_ERROR_OK) {
            printf("UnsubscribeUserMetadata failed error is %d reason is %s\n", errorCode, getErrorReason(errorCode));
        } else {
            printf("UnsubscribeUserMetadata success\n");
        }
    }
};

Metadata

Use the Metadata data type to set and manage metadata, containing the following properties:

PropertiesTypeRequiredDefaultDescription
majorRevisionint64_tOptional-1The version control switch:
- -1: Disable the version verification.
- > 0: Enable the version verification. The operation can only be performed if the target version number matches this value.
itemsMetadataItem*OptionalNULLMetadata items.
itemCountsize_tOptional0The number of metadata items.

The MetadataItem data type contains the following properties:

PropertiesTypeRequiredDefaultDescription
keyconst char*Optional-Key.
valueconst char*Optional-Value.
authorUserIdconst char*Optional-The user ID of the editor. This value is read-only and does not support writing.
revisionint64_tOptional-1
- Returns the real version number in read operations.
- Serves as a version control switch in write operations:
- -1: Disable the version verification.
- > 0: Enable version verification, only perform the operation if the target version number matches this value.
updateTsint64_tOptional0Update timestamp. This value is read-only and does not support writing.

Lock

A critical resource can only be used by one process at a time. If a critical resource is shared between different processes, each process needs to adopt a mutually exclusive method to prevent mutual interference. Signaling provides a full set of lock solutions. By controlling different processes in a distributed system, you can solve the competition problem when users access shared resources.

Information

The client is able to set, remove, and revoke locks. We recommend that you control the permissions of these operations on the client side based on your business needs.

IRtmLock Lock instance

setLock

Description

You need to configure the lock name, time to live (TTL) and other parameters by calling the setLock method.

If the configuration succeeds, all users in the channel receives the onLockEvent event notifications of the RTM_LOCK_EVENT_TYPE_LOCK_SET type. For details, see Event Listeners.

Method

You can call the setLock method as follows:

virtual void setLock(const char* channelName, RTM_CHANNEL_TYPE channelType, const char* lockName, uint32_t ttl, uint64_t& requestId) = 0;
ParametersTypeRequiredDefaultDescription
channelNameconst char*Required-Channel name.
channelTypeRTM_CHANNEL_TYPERequired-Channel types. See RTM_CHANNEL_TYPE.
lockNameconst char*Required-Lock name.
ttluint32_tRequired-The expiration time of the lock. The value is in seconds, ranging from [10 to 300]. When the user who owns the lock goes offline, if the user returns to the channel within the time they can still use the lock; otherwise, the lock is released and the users who listen for the onLockEvent event receives the RTM_LOCK_EVENT_TYPE_LOCK_RELEASED event.
requestIduint64_t&Required-(Output) Request identifier. Use this parameter to identify and process the corresponding request.

Asynchronous callback

After calling this method, the SDK triggers the onSetLockResult callback and return the API execution result through the following parameters:

ParametersTypeDescription
requestIdconst uint64_tRequest identifier.
channelNameconst char*Channel name.
channelTypeRTM_CHANNEL_TYPEChannel type. See RTM_CHANNEL_TYPE.
lockNameconst char*Lock name.
errorCodeRTM_ERROR_CODEError codes.

Basic usage

// Method call
uint64_t requestId;
rtm_client->getLock()->setLock("channelName", RTM_CHANNEL_TYPE_MESSAGE, "lockName", 30, requestId);
// Asynchronous callback
class RtmEventHandler : public IRtmEventHandler {
    void onSetLockResult(const uint64_t requestId, const char *channelName, RTM_CHANNEL_TYPE channelType, const char *lockName, RTM_ERROR_CODE errorCode) {
        if (errorCode != RTM_ERROR_OK) {
            printf("set lock failed error is %d reason is %s\n", errorCode, getErrorReason(errorCode));
        } else {
            printf("set lock success\n");
        }
    }
};

acquireLock

Description

After successfully configuring a lock, you can call the acquireLock method on the client to acquire the right to own the lock.

When you acquire the lock, other users in the channel receives the RTM_LOCK_EVENT_TYPE_LOCK_ACQUIRED type of the onLockEvent event. For details, see Event Listeners.

Method

You can call the acquireLock method as follows:

virtual void acquireLock(const char* channelName, RTM_CHANNEL_TYPE channelType, const char* lockName, bool retry, uint64_t& requestId) = 0;
ParametersTypeRequiredDefaultDescription
channelNameconst char*Required-Channel name.
channelTypeRTM_CHANNEL_TYPERequired-Channel types. See RTM_CHANNEL_TYPE.
lockNameconst char*Required-Lock name.
retryboolRequired-If the lock acquisition fails, whether to retry until the acquisition succeeds or the user leaves the channel.
requestIduint64_t&Required-(Output) Request identifier. Use this parameter to identify and process the corresponding request.

Asynchronous callback

After calling this method, the SDK triggers the onAcquireLockResult callback and return the API execution result through the following parameters:

ParametersTypeDescription
requestIdconst uint64_tRequest identifier.
channelNameconst char*Channel name.
channelTypeRTM_CHANNEL_TYPEChannel type. See RTM_CHANNEL_TYPE.
lockNameconst char*Lock name.
errorCodeRTM_ERROR_CODEError codes.
errorDetailsconst char*Detailed error description.

Basic usage

// Method call
uint64_t requestId;
rtmClient->getLock()->acquireLock("channelName", RTM_CHANNEL_TYPE_MESSAGE, "lockName", false, requestId);
// Asynchronous callback
class RtmEventHandler : public IRtmEventHandler {
    void onAcquireLockResult(const uint64_t requestId, const char *channelName, RTM_CHANNEL_TYPE channelType, const char *lockName, RTM_ERROR_CODE errorCode, const char *errorDetails) {
        if (errorCode != RTM_ERROR_OK) {
            printf("acquire lock failed error is %d reason is %s\n", errorCode, getErrorReason(errorCode));
        } else {
            printf("acquire lock success\n");
        }
    }
};

releaseLock

Description

When a user no longer needs to own a lock, the user can call the releaseLock method on the client side to release the lock.

After successful release the lock, other users in the channel receives the RTM_LOCK_EVENT_TYPE_LOCK_RELEASED type of the onLockEvent event. See Event Listeners.

At this time, if other users want to acquire the lock, they can call the acquireLock method on the client side to compete. New users acquiring locks have the same contention priority as the users who set the retry property to automatically retry to acquire locks.

Method

You can call the releaseLock method as follows:

virtual void releaseLock(const char* channelName, RTM_CHANNEL_TYPE channelType, const char* lockName, uint64_t& requestId) = 0;
ParametersTypeRequiredDefaultDescription
channelNameconst char*Required-Channel name.
channelTypeRTM_CHANNEL_TYPERequired-Channel types. See RTM_CHANNEL_TYPE.
lockNameconst char*Required-Lock name.
requestIduint64_t&Required-(Output) Request identifier. Use this parameter to identify and process the corresponding request.

Asynchronous callback

After calling this method, the SDK triggers the onReleaseLockResult callback and return the API execution result through the following parameters:

ParametersTypeDescription
requestIdconst uint64_tRequest identifier.
channelNameconst char*Channel name.
channelTypeRTM_CHANNEL_TYPEChannel type. See RTM_CHANNEL_TYPE.
lockNameconst char*Lock name.
errorCodeRTM_ERROR_CODEError codes.

Basic usage

// Method call
uint64_t requestId;
rtmClient->getLock()->releaseLock("channelName", RTM_CHANNEL_TYPE_MESSAGE, "lockName", requestId);
// Asynchronous callback
class RtmEventHandler : public IRtmEventHandler {
    void onReleaseLockResult(const uint64_t requestId, const char *channelName, RTM_CHANNEL_TYPE channelType, const char *lockName, RTM_ERROR_CODE errorCode) {
        if (errorCode != RTM_ERROR_OK) {
            printf("release lock failed error is %d reason is %s\n", errorCode, getErrorReason(errorCode));
        } else {
            printf("release lock success\n");
        }
    }
};

revokeLock

Description

When the lock is occupied, to ensure that your business is not affected, you may need to revoke the lock and give other users a chance to obtain it. Revoke the occupied lock by calling revokeLock.

When the lock is revoked, all users in the channel receives the RTM_LOCK_EVENT_TYPE_LOCK_RELEASED type of the onLockEvent event. See Event Listeners.

At this time, if other users want to acquire the lock, they can call the acquireLock method on the client side to compete. New users acquiring locks have the same contention priority as the users who set the retry property to automatically retry to acquire locks.

Method

You can call the revokeLock method as follows:

virtual void revokeLock(const char* channelName, RTM_CHANNEL_TYPE channelType, const char* lockName, const char* owner, uint64_t& requestId) = 0;
ParametersTypeRequiredDefaultDescription
channelNameconst char*Required-Channel name.
channelTypeRTM_CHANNEL_TYPERequired-Channel types. See RTM_CHANNEL_TYPE.
lockNameconst char*Required-Lock name.
ownerconst char*Required-The ID of the user who has a lock.
requestIduint64_t&Required-(Output) Request identifier. Use this parameter to identify and process the corresponding request.

Asynchronous callback

After calling this method, the SDK triggers the onRevokeLockResult callback and return the API execution result through the following parameters:

ParametersTypeDescription
requestIdconst uint64_tRequest identifier.
channelNameconst char*Channel name.
channelTypeRTM_CHANNEL_TYPEChannel type. See RTM_CHANNEL_TYPE.
lockNameconst char*Lock name.
errorCodeRTM_ERROR_CODEError codes.

Basic usage

// Method call
uint64_t requestId;
rtmClient->getLock()->revokeLock("channelName", RTM_CHANNEL_TYPE_MESSAGE, "lockName", "tony", requestId);
// Asynchronous callback
class RtmEventHandler : public IRtmEventHandler {
    void onRevokeLockResult(const uint64_t requestId, const char *channelName, RTM_CHANNEL_TYPE channelType, const char *lockName, RTM_ERROR_CODE errorCode) {
        if (errorCode != RTM_ERROR_OK) {
            printf("revoke lock failed error is %d reason is %s\n", errorCode, getErrorReason(errorCode));
        } else {
            printf("revoke lock success\n");
        }
    }
};

getMessages

Description

If you want to query the lock information such as lock total number, lock name, and lock user, time to live, you can call the getMessages method on the client.

Method

You can call the getMessages method as follows:

virtual void getLocks(const char* channelName, RTM_CHANNEL_TYPE channelType, uint64_t& requestId) = 0;
ParametersTypeRequiredDefaultDescription
channelNameconst char*Required-Channel name.
channelTypeRTM_CHANNEL_TYPERequired-Channel types. See RTM_CHANNEL_TYPE.
requestIduint64_t&Required-(Output) Request identifier. Use this parameter to identify and process the corresponding request.

Asynchronous callback

After calling this method, the SDK triggers the onGetLocksResult callback and return the API execution result through the following parameters:

ParametersTypeDescription
requestIdconst uint64_tRequest identifier.
channelNameconst char*Channel name.
channelTypeRTM_CHANNEL_TYPEChannel type. See RTM_CHANNEL_TYPE.
lockDetailListconst LockDetail*Details of lock.
countconst size_tLock count.
errorCodeRTM_ERROR_CODEError codes.

The LockDetail data type contains the following properties:

PropertiesTypeDescription
lockNameconst char*Lock name.
ownerconst char*The ID of the user who has a lock.
ttluint32_tThe expiration time of the lock. The value is in seconds, ranging from [10 to 300]. When the user who owns the lock goes offline, if the user returns to the channel within the time they can still use the lock; otherwise, the lock is released and the users who listen for the onLockEvent event receives the RTM_LOCK_EVENT_TYPE_LOCK_RELEASED event.

Basic usage

// Method call
uint64_t requestId;
rtmClient->getLock()->getLocks("channelName", RTM_CHANNEL_TYPE_MESSAGE, requestId);
// Asynchronous callback
class RtmEventHandler : public IRtmEventHandler {
    void onGetLocksResult(const uint64_t requestId, const char *channelName, RTM_CHANNEL_TYPE channelType, const LockDetail *lockDetailList, const size_t count, RTM_ERROR_CODE errorCode) override {
        if (errorCode != RTM_ERROR_OK) {
            printf("get lock failed error is %d reason is %s\n", errorCode, getErrorReason(errorCode));
        } else {
            printf("get lock success\n");
            for (int i = 0 ; i < count; i++) {
                printf("lock: %s owner: %s ttl: %d\n", lockDetailList[i].lockName, lockDetailList[i].owner, lockDetailList[i].ttl);
            }
        }
    }
};

removeLock

Description

If you no longer need a lock, you can call the removeLock method to remove the lock.

After successfully removing the lock, all users in the channel receives the RTM_LOCK_EVENT_TYPE_LOCK_REMOVED type of onLockEvent event notification. See Event Listeners.

Method

You can call the removeLock method as follows:

virtual void removeLock(const char* channelName, RTM_CHANNEL_TYPE channelType, const char* lockName, uint64_t& requestId) = 0;
ParametersTypeRequiredDefaultDescription
channelNameconst char*Required-Channel name.
channelTypeRTM_CHANNEL_TYPERequired-Channel types. See RTM_CHANNEL_TYPE.
lockNameconst char*Required-Lock name.
requestIduint64_t&Required-(Output) Request identifier. Use this parameter to identify and process the corresponding request.

Asynchronous callback

After calling this method, the SDK triggers the onRemoveLockResult callback and return the API execution result through the following parameters:

ParametersTypeDescription
requestIdconst uint64_tRequest identifier.
channelNameconst char*Channel name.
channelTypeRTM_CHANNEL_TYPEChannel type. See RTM_CHANNEL_TYPE.
lockNameconst char*Lock name.
errorCodeRTM_ERROR_CODEError codes.

Basic usage

// Method call
uint64_t requestId;
rtmClient->getLock()->removeLock("channelName", RTM_CHANNEL_TYPE_MESSAGE, "lockName", requestId);
// Asynchronous callback
class RtmEventHandler : public IRtmEventHandler {
    void onRemoveLockResult(const uint64_t requestId, const char *channelName, RTM_CHANNEL_TYPE channelType, const char *lockName, RTM_ERROR_CODE errorCode) override {
        if (errorCode != RTM_ERROR_OK) {
            printf("remove lock failed error is %d reason is %s\n", errorCode, getErrorReason(errorCode));
        } else {
            printf("remove lock success\n");
        }
    }
};

Enumerated types

RTM_AREA_CODE

The region for connection, which is the region where the server the SDK connects to is located.

ValueDescription
RTM_AREA_CODE_CN0x00000001: Mainland China.
RTM_AREA_CODE_NA0x00000002: North America.
RTM_AREA_CODE_EU0x00000004: Europe.
RTM_AREA_CODE_AS0x00000008: Asia, excluding Mainland China.
RTM_AREA_CODE_JP0x00000010: Japan.
RTM_AREA_CODE_IN0x00000020: India.
RTM_AREA_CODE_GLOB0xFFFFFFFF: Global.

RTM_CHANNEL_TYPE

Channel types.

ValueDescription
RTM_CHANNEL_TYPE_MESSAGE1: Message channel.
RTM_CHANNEL_TYPE_STREAM2: Stream channel.
RTM_CHANNEL_TYPE_USER3: User Channel.

RTM_CONNECTION_CHANGE_REASON

Reasons causing the change of the connection state.

ValueDescription
RTM_CONNECTION_CHANGED_CONNECTING0: The SDK is connecting with the server.
RTM_CONNECTION_CHANGED_JOIN_SUCCESS1: The SDK has joined the channel successfully.
RTM_CONNECTION_CHANGED_INTERRUPTED2: The connection between the SDK and the server is interrupted.
RTM_CONNECTION_CHANGED_BANNED_BY_SERVER3: The connection between the SDK and the server is banned by the server.
RTM_CONNECTION_CHANGED_JOIN_FAILED4: The SDK fails to join the channel. When the SDK fails to join the channel for more than 20 minutes, this error occurs and the SDK stops reconnecting to the channel.
RTM_CONNECTION_CHANGED_LEAVE_CHANNEL5: The SDK has left the channel.
RTM_CONNECTION_CHANGED_INVALID_APP_ID6: The connection failed because the App ID is not valid.
RTM_CONNECTION_CHANGED_INVALID_CHANNEL_NAME7: The connection failed because the channel name is not valid.
RTM_CONNECTION_CHANGED_INVALID_TOKEN8: The connection failed because the token is not valid.
RTM_CONNECTION_CHANGED_TOKEN_EXPIRED9: The connection failed because the token is expired.
RTM_CONNECTION_CHANGED_REJECTED_BY_SERVER10: The connection is rejected by server.
RTM_CONNECTION_CHANGED_SETTING_PROXY_SERVER11: The connection state changed to reconnecting because the SDK has set a proxy server.
RTM_CONNECTION_CHANGED_RENEW_TOKEN12: The connection state changed because the token is renewed.
RTM_CONNECTION_CHANGED_CLIENT_IP_ADDRESS_CHANGED13: The IP address of the client has changed, possibly because the network type, IP address, or port has been changed.
RTM_CONNECTION_CHANGED_KEEP_ALIVE_TIMEOUT14: Timeout for the keep-alive of the connection between the SDK and the server. The connection state changes to reconnecting.
RTM_CONNECTION_CHANGED_REJOIN_SUCCESS15: The user has rejoined the channel successfully.
RTM_CONNECTION_CHANGED_LOST16: The connection between the SDK and the server is lost.
RTM_CONNECTION_CHANGED_ECHO_TEST17: The connection state changes due to the echo test.
RTM_CONNECTION_CHANGED_CLIENT_IP_ADDRESS_CHANGED_BY_USER18: The local IP address was changed by the user. The connection state changes to reconnecting.
RTM_CONNECTION_CHANGED_SAME_UID_LOGIN19: The user joined the same channel from different devices with the same UID.
RTM_CONNECTION_CHANGED_TOO_MANY_BROADCASTERS20: The number of hosts in the channel has reached the upper limit.
RTM_CONNECTION_CHANGED_LICENSE_VALIDATION_FAILURE21: License validation failure.
RTM_CONNECTION_CHANGED_CERTIFICATION_VERIFY_FAILURE22: The server certificate verification has encountered an error.
RTM_CONNECTION_CHANGED_STREAM_CHANNEL_NOT_AVAILABLE23: The stream channel does not exist.
RTM_CONNECTION_CHANGED_INCONSISTENT_APPID24: The App ID does not match the token.
RTM_CONNECTION_CHANGED_LOGIN_SUCCESS10001: The SDK logs in to the Signaling system.
RTM_CONNECTION_CHANGED_LOGOUT10002: The SDK logs out from the Signaling system.
RTM_CONNECTION_CHANGED_PRESENCE_NOT_READY10003: Presence service is not ready. You need to call the login method again to log in to the Signaling system and re-execute all operations on the SDK.

RTM_CONNECTION_STATE

SDK connection states.

ValueDescription
RTM_CONNECTION_STATE_DISCONNECTED1: The SDK has disconnected with the server.
RTM_CONNECTION_STATE_CONNECTING2: The SDK is connecting with the server.
RTM_CONNECTION_STATE_CONNECTED3: The SDK has connected with the server.
RTM_CONNECTION_STATE_RECONNECTING4: The connection is lost. The SDK is reconnecting with the server.
RTM_CONNECTION_STATE_FAILED5: The SDK failed to connect with the server.

RTM_ENCRYPTION_MODE

Encryption mode.

ValueDescription
RTM_ENCRYPTION_MODE_NONE0: No encryption.
RTM_ENCRYPTION_MODE_AES_128_GCM1: AES-128-GCM mode.
RTM_ENCRYPTION_MODE_AES_256_GCM2: AES-256-GCM mode.

RTM_LOCK_EVENT_TYPE

Lock event type.

ValueDescription
RTM_LOCK_EVENT_TYPE_SNAPSHOT1: The snapshot of the lock when the user joined the channel.
RTM_LOCK_EVENT_TYPE_LOCK_SET2: The lock is set.
RTM_LOCK_EVENT_TYPE_LOCK_REMOVED3: The lock is removed.
RTM_LOCK_EVENT_TYPE_LOCK_ACQUIRED4: The lock is acquired.
RTM_LOCK_EVENT_TYPE_LOCK_RELEASED5: The lock is released.
RTM_LOCK_EVENT_TYPE_LOCK_EXPIRED6: The lock expired.

RTM_LOG_LEVEL

Log output levels.

ValueDescription
RTM_LOG_LEVEL_NONE0x0000: No log.
RTM_LOG_LEVEL_INFO0x0001: Output the log at the FATAL, ERROR, WARN, or INFO level. We recommend you set to this value.
RTM_LOG_LEVEL_WARN0x0002: Output the log at the FATAL, ERROR, WARN level.
RTM_LOG_LEVEL_ERROR0x0004: Output the log at the FATAL, ERROR level.
RTM_LOG_LEVEL_FATAL0x0008: Output the log at the FATAL level.

RTM_MESSAGE_PRIORITY

Message priority.

ValueDescription
RTM_MESSAGE_PRIORITY_HIGHEST0: Highest.
RTM_MESSAGE_PRIORITY_HIGH1: High.
RTM_MESSAGE_PRIORITY_NORMAL4: Normal.
RTM_MESSAGE_PRIORITY_LOW8: Low.

RTM_MESSAGE_QOS

QoS guarantee when sending topic messages.

ValueDescription
RTM_MESSAGE_QOS_UNORDERED0: Message data is not guaranteed to arrive in order.
RTM_MESSAGE_QOS_ORDERED1: Message data arrives in order.

RTM_MESSAGE_TYPE

Message type.

ValueDescription
RTM_MESSAGE_TYPE_BINARY0: Binary type.
RTM_MESSAGE_TYPE_STRING1: String type.

RTM_PRESENCE_EVENT_TYPE

Presence event type.

ValueDescription
RTM_PRESENCE_EVENT_TYPE_SNAPSHOT1: The snapshot of the presence when the user joined the channel.
RTM_PRESENCE_EVENT_TYPE_INTERVAL2: When users in the channel reach the setting value, the event notifications are sent at intervals rather than in real time.
RTM_PRESENCE_EVENT_TYPE_REMOTE_JOIN_CHANNEL3: A remote user joined the channel.
RTM_PRESENCE_EVENT_TYPE_REMOTE_LEAVE_CHANNEL4: A remote user left the channel.
RTM_PRESENCE_EVENT_TYPE_REMOTE_TIMEOUT5: A remote user's connection timed out.
RTM_PRESENCE_EVENT_TYPE_REMOTE_STATE_CHANGED6: A remote user's temporary state changed.
RTM_PRESENCE_EVENT_TYPE_ERROR_OUT_OF_SERVICE7: The user did not enable presence when joining the channel.

Operation type.

ValueDescription
RTM_LINK_OPERATION_LOGIN0: The user logins to the Signaling system.
RTM_LINK_OPERATION_LOGOUT1: The user logouts of the Signaling system.
RTM_LINK_OPERATION_JOIN2: The user joins in a stream channel.
RTM_LINK_OPERATION_LEAVE3: The user leaves a stream channel.
RTM_LINK_OPERATION_SERVER_REJECT4: The Signaling server reject the connection.
RTM_LINK_OPERATION_AUTO_RECONNECT5: The SDK is automatically reconnecting to the Signaling server.
RTM_LINK_OPERATION_RECONNECTED6: The SDK is reconnected to the Signaling server.
RTM_LINK_OPERATION_HEARTBEAT_LOST7: The Signaling server does not receive the heartbeat packet within the specified timeout period.
RTM_LINK_OPERATION_SERVER_TIMEOUT8: The Signaling server has timed out.
RTM_LINK_OPERATION_NETWORK_CHANGE9: The network status changes.

Link state type.

ValueDescription
RTM_LINK_STATE_IDLE0: The init state.
RTM_LINK_STATE_CONNECTING1: Connecting.
RTM_LINK_STATE_CONNECTED2: Connected.
RTM_LINK_STATE_DISCONNECTED3: Disconnected.
RTM_LINK_STATE_SUSPENDED4: Suspended.
RTM_LINK_STATE_FAILED5: Failed.

Link state change reason.

ValueDescription
RTM_LINK_STATE_CHANGE_REASON_UNKNOWN0: Unknown reason.
RTM_LINK_STATE_CHANGE_REASON_LOGIN1: Logging in.
RTM_LINK_STATE_CHANGE_REASON_LOGIN_SUCCESS2: Login successful.
RTM_LINK_STATE_CHANGE_REASON_LOGIN_TIMEOUT3: Login timeout.
RTM_LINK_STATE_CHANGE_REASON_LOGIN_NOT_AUTHORIZED4: Login not authorized.
RTM_LINK_STATE_CHANGE_REASON_LOGIN_REJECTED5: Login rejected.
RTM_LINK_STATE_CHANGE_REASON_RELOGIN6: Re-login.
RTM_LINK_STATE_CHANGE_REASON_LOGOUT7: Logout.
RTM_LINK_STATE_CHANGE_REASON_AUTO_RECONNECT8: Auto-reconnect.
RTM_LINK_STATE_CHANGE_REASON_RECONNECT_TIMEOUT9: Reconnect timeout.
RTM_LINK_STATE_CHANGE_REASON_RECONNECT_SUCCESS10: Reconnect successful.
RTM_LINK_STATE_CHANGE_REASON_JOIN11: Joining a channel.
RTM_LINK_STATE_CHANGE_REASON_JOIN_SUCCESS12: Join channel successful.
RTM_LINK_STATE_CHANGE_REASON_JOIN_FAILED13: Join channel failed.
RTM_LINK_STATE_CHANGE_REASON_REJOIN14: Re-join a channel.
RTM_LINK_STATE_CHANGE_REASON_LEAVE15: Leave a channel.
RTM_LINK_STATE_CHANGE_REASON_INVALID_TOKEN16: Invalid token.
RTM_LINK_STATE_CHANGE_REASON_TOKEN_EXPIRED17: Token expired.
RTM_LINK_STATE_CHANGE_REASON_INCONSISTENT_APP_ID18: Inconsistent app ID.
RTM_LINK_STATE_CHANGE_REASON_INVALID_CHANNEL_NAME19: Invalid channel name.
RTM_LINK_STATE_CHANGE_REASON_INVALID_USER_ID20: Invalid user ID.
RTM_LINK_STATE_CHANGE_REASON_NOT_INITIALIZED21: SDK not initialized.
RTM_LINK_STATE_CHANGE_REASON_RTM_SERVICE_NOT_CONNECTED22: RTM service not connected.
RTM_LINK_STATE_CHANGE_REASON_CHANNEL_INSTANCE_EXCEED_LIMITATION23: Channel instance exceeds the limit.
RTM_LINK_STATE_CHANGE_REASON_OPERATION_RATE_EXCEED_LIMITATION24: Operation frequency exceeds the limit.
RTM_LINK_STATE_CHANGE_REASON_CHANNEL_IN_ERROR_STATE25: Channel in error state.
RTM_LINK_STATE_CHANGE_REASON_PRESENCE_NOT_CONNECTED26: Presence service not connected.
RTM_LINK_STATE_CHANGE_REASON_SAME_UID_LOGIN27: Login with the same user ID.
RTM_LINK_STATE_CHANGE_REASON_KICKED_OUT_BY_SERVER28: Kicked out by the server.
RTM_LINK_STATE_CHANGE_REASON_KEEP_ALIVE_TIMEOUT29: Keepalive timeout.
RTM_LINK_STATE_CHANGE_REASON_CONNECTION_ERROR30: Connection error.
RTM_LINK_STATE_CHANGE_REASON_PRESENCE_NOT_READY31: Presence service not ready.
RTM_LINK_STATE_CHANGE_REASON_NETWORK_CHANGE32: Network changed.
RTM_LINK_STATE_CHANGE_REASON_SERVICE_NOT_SUPPORTED33: Service not supported.
RTM_LINK_STATE_CHANGE_REASON_STREAM_CHANNEL_NOT_AVAILABLE34: Stream Channel not available.
RTM_LINK_STATE_CHANGE_REASON_STORAGE_NOT_AVAILABLE35: Storage service not available.
RTM_LINK_STATE_CHANGE_REASON_LOCK_NOT_AVAILABLE36: Lock service not available.
RTM_LINK_STATE_CHANGE_REASON_LOGIN_TOO_FREQUENT37: The login operation is too frequent.

RTM_PROTOCOL_TYPE

Protocol type.

ValueDescription
RTM_PROTOCOL_TYPE_TCP_UDP0: Both TCP and UDP protocols.
RTM_PROTOCOL_TYPE_TCP_ONLY1: Only TCP protocol.

RTM_SERVICE_TYPE

Service type

ValueDescription
RTM_SERVICE_TYPE_MESSAGEThe foundational services comprise the message channel, user channel, presence, storage, and lock services.
RTM_SERVICE_TYPE_STREAMThe stream channel service.

Information

To fully utilize all services offered by Signaling, you can employ bitwise operations to simultaneously configure two service types.

RTM_PROXY_TYPE

Proxy type.

ValueDescription
RTM_PROXY_TYPE_NONE0: Do not enable the proxy.
RTM_PROXY_TYPE_HTTP1: Enable the proxy for the HTTP protocol.
RTM_PROXY_TYPE_CLOUD_TCP2: Enable cloud proxy for the TCP protocol.

RTM_STORAGE_EVENT_TYPE

Storage event type.

ValueDescription
RTM_STORAGE_EVENT_TYPE_SNAPSHOT1: When a user subscribes to channel metadata or user etadata for the first time, or joins a channel, the local user receives notifications of this type of event.
RTM_STORAGE_EVENT_TYPE_SET2: Occurs when calling setChannelMetadata or setUserMetadata. Caution: This event only occurs in incremental data update mode.
RTM_STORAGE_EVENT_TYPE_UPDATE3: Occurs when calling methods to set, update, or delete the channel metadata or user metadata.
RTM_STORAGE_EVENT_TYPE_REMOVE4: Occurs when calling removeChannelMetadata or removeUserMetadata. Caution: This event only occurs in incremental data update mode.

RTM_STORAGE_TYPE

Storage type.

ValueDescription
RTM_STORAGE_TYPE_USER1: User metadata event.
RTM_STORAGE_TYPE_CHANNEL2: Channel metadata event.

RTM_TOPIC_EVENT_TYPE

Topic event type.

ValueDescription
RTM_TOPIC_EVENT_TYPE_SNAPSHOT1: The snapshot of the topic when the user joined the channel.
RTM_TOPIC_EVENT_TYPE_REMOTE_JOIN_TOPIC2: A remote user joined the topic.
RTM_TOPIC_EVENT_TYPE_REMOTE_LEAVE_TOPIC3: A remote user left the topic.

Troubleshooting

Refer to the following information for troubleshooting API calls.

ErrorInfo

Error codes table

Refer to the following error codes table to identify and troubleshoot the problem:

Error codeError descriptionCause and solution
0RTM_ERROR_OKCorrect call
-10001RTM_ERROR_NOT_INITIALIZEDThe SDK is not initialized. Please initialize the RtmClient instance by calling the createAgoraRtmClient method before performing other operations.
-10002RTM_ERROR_NOT_LOGINThe user called the API without logging in to Signaling, disconnected due to timeout, or actively logged out. Please log in to Signaling first.
-10003RTM_ERROR_INVALID_APP_IDInvalid App ID:
- Check that the App ID is correct.
- Ensure that Signaling has been activated for the App ID.
-10005RTM_ERROR_INVALID_TOKENInvalid Token:
- The token is invalid, check whether the Token Provider generates a valid Signaling Token.
-10006RTM_ERROR_INVALID_USER_IDInvalid User ID:
- Check if user ID is empty.
- Check if the user ID contains illegal characters.
-10007RTM_ERROR_INIT_SERVICE_FAILEDSDK initialization failed. Please reinitialize by calling the createAgoraRtmClient method.
-10008RTM_ERROR_INVALID_CHANNEL_NAMEInvalid channel name:
- Check if the channel name is empty.
- Check if the channel name contains illegal characters.
-10009RTM_ERROR_TOKEN_EXPIREDToken expired. Call renewToken to reacquire the Token.
-10010RTM_ERROR_LOGIN_NO_SERVER_RESOURCESServer resources are limited. It is recommended to log in again.
-10011RTM_ERROR_LOGIN_TIMEOUTLogin timeout. Check whether the current network is stable and switch to a stable network environment.
-10012RTM_ERROR_LOGIN_REJECTEDSDK login rejected by the server:
- Check tha Signaling is activated on your App ID.
- Check if the token or userId is banned.
-10013RTM_ERROR_LOGIN_ABORTEDSDK login interrupted due to unknown problem:
- Check that the current network is stable and switch to a stable network environment.
- The current userId is logged in.
-10014RTM_ERROR_INVALID_PARAMETERInvalid parameter. Please check if the parameters you provided are correct.
-10015RTM_ERROR_LOGIN_NOT_AUTHORIZEDNo RTM service permissions. Check that the console opens Signaling services.
-10016RTM_ERROR_INCONSISTENT_APPIDInconsistent App ID. Please check whether the App ID used for initialization, login, and joining a channel are consistent.
-10017RTM_ERROR_DUPLICATE_OPERATIONDuplicate operation.
-10018RTM_ERROR_INSTANCE_ALREADY_RELEASEDRepeat rtm instantiation or RTMStreamChannel instantiation.
-10019RTM_ERROR_INVALID_CHANNEL_TYPEInvalid channel type. The SDK only supports the following channel types. Please use the correct value:
- RTM_CHANNEL_TYPE_MESSAGE: Message Channel
- RTM_CHANNEL_TYPE_STREAM: Stream Channel
- RTM_CHANNEL_TYPE_USER: User Channel
-10020RTM_ERROR_INVALID_ENCRYPTION_PARAMETERMessage encryption parameters are invalid.
- Check that the encryption key generated is a String.
- Check that the generated encryption salt is Uint8Array type and that the length is 32 bytes.
- Check that the encryption method matches the encryption key and the encryption salt.
-10021RTM_ERROR_OPERATION_RATE_EXCEED_LIMITATIONChannel metadata or User Metadata -related API call frequency is exceeding the limit. Please control the call frequency within 10/second.
-10022RTM_ERROR_SERVICE_NOT_SUPPORTEDThe service type is not supported. Check whether the service type you set in RTM_SERVICE_TYPE is correct. This error code is only applicable to the private deployment function.
-10023RTM_ERROR_LOGIN_CANCELEDThe login operation has been canceled. Possible reasons are as follows:
- After calling the login method, if you call the method again before receiving the call result, the previous call operation will be canceled and the SDK will execute the next call.
- Calling the logout method to log out before successfully logging in.
-10024RTM_ERROR_INVALID_PRIVATE_CONFIGThe private deployment parameter settings are invalid. Please check whether the service type and server address you set in RtmPrivateConfig are valid.
-10025RTM_ERROR_NOT_CONNECTEDNot connected to the Signaling server. When you call APIs related to message subscription, metadata, or the Lock module, this error is reported if the Signaling service is not connected.
-10026RTM_ERROR_RENEW_TOKEN_TIMEOUTToken renewal timed out.
-11001RTM_ERROR_CHANNEL_NOT_JOINEDThe user has not joined the channel:
- The user is not online, offline or has not joined the channel
- Check for typos in userId.
-11002RTM_ERROR_CHANNEL_NOT_SUBSCRIBEDThe user has not subscribed to the channel:
- The user is not online, offline or has not joined the channel
- Check for typos in userId.
-11003RTM_ERROR_CHANNEL_EXCEED_TOPIC_USER_LIMITATIONThe number of subscribers to this topic exceeds the limit.
-11004RTM_ERROR_CHANNEL_IN_REUSEIn co-channel mode, RTM released the Stream Channel.
-11005RTM_ERROR_CHANNEL_INSTANCE_EXCEED_LIMITATIONThe number of created or subscribed channels exceeds the limit. See API usage limits for details.
-11006RTM_ERROR_CHANNEL_IN_ERROR_STATEChannel is not available. Please recreate the Stream Channel or resubscribe to the Message Channel.
-11007RTM_ERROR_CHANNEL_JOIN_FAILEDFailed to join this channel:
- Check if the number of joined channels exceeds the limit.
- Check if the channel name is illegal.
- Check if the network is disconnected.
-11008RTM_ERROR_CHANNEL_INVALID_TOPIC_NAMEInvalid topic name:
- Check whether the topic name contains illegal characters.
- Check if the topic name is empty.
-11009RTM_ERROR_CHANNEL_INVALID_MESSAGEInvalid message. Check whether the message type is legal, Signaling only supports string, Uint8Array type messages.
-11010RTM_ERROR_CHANNEL_MESSAGE_LENGTH_EXCEED_LIMITATIONMessage length exceeded limit. Check if the message payload size exceeds the limit:
- Message Channel single message package limit is 32 KB.
- Stream Channel single message package limit is 1 KB.
-11011RTM_ERROR_CHANNEL_INVALID_USER_LISTInvalid user list:
- Check if the user list is empty.
- Check if the user list contains invalid entries.
-11012RTM_ERROR_CHANNEL_NOT_AVAILABLEInvalid user list:
- Check if the user list is empty
- Check if the user list contains illegal items.
-11013RTM_ERROR_CHANNEL_TOPIC_NOT_SUBSCRIBEDThe topic is not subscribed.
-11014RTM_ERROR_CHANNEL_EXCEED_TOPIC_LIMITATIONThe number of topics exceeds the limit.
-11015RTM_ERROR_CHANNEL_JOIN_TOPIC_FAILEDFailed to join this topic. Check whether the number of added topics exceeds the limit.
-11016RTM_ERROR_CHANNEL_TOPIC_NOT_JOINEDThe topic has not been joined. To send a message, you need to join the Topic first.
-11017RTM_ERROR_CHANNEL_TOPIC_NOT_EXISTThe topic does not exist. Check that the topic name is correct.
-11018RTM_ERROR_CHANNEL_INVALID_TOPIC_METAThe meta parameters in the topic are invalid. Check if the meta parameter exceeds 256 bytes.
-11019RTM_ERROR_CHANNEL_SUBSCRIBE_TIMEOUTChannel subscription timed out. Check for broken connections.
-11020RTM_ERROR_CHANNEL_SUBSCRIBE_TOO_FREQUENTThe channel subscription operation is too frequent. Make sure that the subscription operation of the same channel within a 5 seconds interval does not exceed 2 attempts.
-11021RTM_ERROR_CHANNEL_SUBSCRIBE_FAILEDChannel subscription failed. Check if the number of subscribed channels exceeds the limit.
-11022RTM_ERROR_CHANNEL_UNSUBSCRIBE_FAILEDFailed to unsubscribe from the channel. Check if the connection is disconnected.
-11023RTM_ERROR_CHANNEL_ENCRYPT_MESSAGE_FAILEDMessage encryption failed:
- Check that the cipherKey is valid.
- Check that the salt is valid.
- Check if encryptionMode mode matches the cipherKey and salt.
-11024RTM_ERROR_CHANNEL_PUBLISH_MESSAGE_FAILEDMessage publishing failed. Check for broken connections.
-11026RTM_ERROR_CHANNEL_PUBLISH_MESSAGE_TIMEOUTMessage publishing timed out. Check for broken connections.
-11027RTM_ERROR_CHANNEL_NOT_CONNECTEDThe SDK is disconnected from the Signaling server. Please log in again.
-11028RTM_ERROR_CHANNEL_LEAVE_FAILEDFailed to leave the channel. Check for broken connections.
-11029RTM_ERROR_CHANNEL_CUSTOM_TYPE_LENGTH_OVERFLOWCustom type length overflow. The length of the customType field must to be within 32 characters.
-11030RTM_ERROR_CHANNEL_INVALID_CUSTOM_TYPEcustomType field is invalid. Check the customType field for illegal characters.
-11031RTM_ERROR_CHANNEL_UNSUPPORTED_MESSAGE_TYPEMessage type is not supported.
-11032RTM_ERROR_CHANNEL_PRESENCE_NOT_READYPresence service is not ready. Please rejoin the Stream Channel or resubscribe to the Message Channel.
-11033RTM_ERROR_CHANNEL_RECEIVER_OFFLINEWhen sending a user message, the remote user is offline:
- Check if the user ID set when calling the method is correct.
- Check if the remote user is logged in and online.
-11034RTM_ERROR_CHANNEL_JOIN_CANCELEDThe join channel operation has been canceled. After calling the joinTopic method, if you call the method again before receiving the call result, the previous call operation will be canceled and the SDK will execute the next call.
-12001RTM_ERROR_STORAGE_OPERATION_FAILEDStorage operation failed.
-12002RTM_ERROR_STORAGE_METADATA_ITEM_EXCEED_LIMITATIONThe number of Storage Metadata Items exceeds the limit.
-12003RTM_ERROR_STORAGE_INVALID_METADATA_ITEMInvalid Metadata Item.
-12004RTM_ERROR_STORAGE_INVALID_ARGUMENTInvalid argument.
-12005RTM_ERROR_STORAGE_INVALID_REVISIONInvalid Revision parameter.
-12006RTM_ERROR_STORAGE_METADATA_LENGTH_OVERFLOWMetadata overflows.
-12007RTM_ERROR_STORAGE_INVALID_LOCK_NAMEInvalid Lock name.
-12008RTM_ERROR_STORAGE_LOCK_NOT_ACQUIREDThe Lock was not acquired.
-12009RTM_ERROR_STORAGE_INVALID_KEYInvalid Metadata key.
-12010RTM_ERROR_STORAGE_INVALID_VALUEInvalid metadata value.
-12011RTM_ERROR_STORAGE_KEY_LENGTH_OVERFLOWMetadata key length overflow.
-12012RTM_ERROR_STORAGE_VALUE_LENGTH_OVERFLOWMetadata value length overflow.
-12013RTM_ERROR_STORAGE_DUPLICATE_KEYDuplicate Metadata Item key.
-12014RTM_ERROR_STORAGE_OUTDATED_REVISIONOutdated Revision parameter.
-12015RTM_ERROR_STORAGE_NOT_SUBSCRIBEThis channel is not subscribed.
-12016RTM_ERROR_STORAGE_INVALID_METADATA_INSTANCEMetadata instance does not exist. Please create a Metadata instance.
-12017RTM_ERROR_STORAGE_SUBSCRIBE_USER_EXCEED_LIMITATIONThe number of subscribers exceeds the limit.
-12018RTM_ERROR_STORAGE_OPERATION_TIMEOUTStorage operation timed out.
-12019RTM_ERROR_STORAGE_NOT_AVAILABLEThe Storage service is not available.
-13001RTM_ERROR_PRESENCE_NOT_CONNECTEDThe user is not connected to the system.
-13002RTM_ERROR_PRESENCE_NOT_WRITABLEPresence service is unavailable.
-13003RTM_ERROR_PRESENCE_INVALID_ARGUMENTInvalid argument.
-13004RTM_ERROR_PRESENCE_CACHED_TOO_MANY_STATESThe temporary user state cached before joining the channel exceeds the limit. See API usage limits for details.
-13005RTM_ERROR_PRESENCE_STATE_COUNT_OVERFLOWThe number of temporary user state key/value pairs exceeds the limit. See API usage limits for details.
-13006RTM_ERROR_PRESENCE_INVALID_STATE_KEYInvalid state key.
-13007RTM_ERROR_PRESENCE_INVALID_STATE_VALUEInvalid state value.
-13008RTM_ERROR_PRESENCE_STATE_KEY_SIZE_OVERFLOWPresence key length overflow.
-13009RTM_ERROR_PRESENCE_STATE_VALUE_SIZE_OVERFLOWPresence value overflow
-13010RTM_ERROR_PRESENCE_STATE_DUPLICATE_KEYRepeated state key.
-13011RTM_ERROR_PRESENCE_USER_NOT_EXISTThe user does not exist.
-13012RTM_ERROR_PRESENCE_OPERATION_TIMEOUTPresence operation timed out.
-13013RTM_ERROR_PRESENCE_OPERATION_FAILEDPresence operation failed.
-14001RTM_ERROR_LOCK_OPERATION_FAILEDLock operation failed.
-14002RTM_ERROR_LOCK_OPERATION_TIMEOUTLock operation timed out.
-14003RTM_ERROR_LOCK_OPERATION_PERFORMINGLock operation in progress.
-14004RTM_ERROR_LOCK_ALREADY_EXISTLock already exists.
-14005RTM_ERROR_LOCK_INVALID_NAMEInvalid Lock name.
-14006RTM_ERROR_LOCK_NOT_ACQUIREDThe Lock was not acquired.
-14007RTM_ERROR_LOCK_ACQUIRE_FAILEDFailed to acquire the Lock.
-14008RTM_ERROR_LOCK_NOT_EXISTThe Lock does not exist.
-14009RTM_ERROR_LOCK_NOT_AVAILABLELock service is not available.