This article describes the best practices of RESTful API calls and SDK integration.
If a RTM RESTful API request to api.agora.io
fails, retry with the same domain name first. If the request fails again, replace the domain name with api.sd-rtn.com
and retry. Agora recommends that you use a backoff strategy to retry a failed request after a given delay, for example, retry after 1, 3, and 6 seconds successively. This avoids exceeding the Queries Per Second (QPS) limits.
(All SDKs) An RTM token stays valid for 24 hours. Agora recommends that you generate the token from your server and call renewToken
to update the token for the SDK at a fixed interval, such as one hour. See Generate an RTM Token to learn more about generating a token from your server.
The following code example shows how to update the token at a fixed interval:
// C++
// Monitor the callback for token expiration
class MyHandler : public IRtmServiceEventHandler {
public:
void onRenewTokenResult(const char* token, RENEW_TOKEN_ERR_CODE errorCode)
{
if (errorCode == RENEW_TOKEN_ERR_OK) {
token_ = errorCode;
}
else {
token_ = "";
}
}
void setToken(const std::string& token) {
token_ = token;
}
std::string getNewToken()
{
return token_;
}
private:
std::string token_;
};
// Get the token generated from the server and update the token for the SDK
void renewTokenDemoCode() {
auto client = createRtmService();
std::string appId = "";
std::string token = "";
std::string userId = "";
bool stopped = false;
MyHandler handler;
handler.setToken(token);
client->initialize("appId", &handler);
client->login(token.c_str(), userId.c_str());
// Wait for login success
sleep(10);
// Token Update token in a single thread
while(!stopped) {
// Update token every hour
sleep(60 * 60);
// Error handling
if (handler.getNewToken().empty()) {
break;
}
client->renewToken(handler.getNewToken().c_str());
}
client->logout();
client->release();
}
(C++ SDK, Java SDK) Memory leaks may occur if you do not release resources in time. Although the GC (Garbage Collection) mechanism of Java can recycle Java objects, the low-level C++ API still uses Java objects for callbacks and may cause the app to crash.
Agora recommends that you call release
to release RTM client objects and channel objects.
(All SDKs) If you have released the RTM client object, Agora recommends that you do not access the related resources. Also, you cannot access the RtmCallManager
object after releasing the RTM client object.
(C++ SDK, Java SDK, Objective-C SDK) If you call release
to release a channel object in a callback of the channel object, the app will hang. The reason is that the callback adds a lock to the object and the release
method requires the same lock.
(C++ SDK) The objects IRtmService
and IChannel
have corresponding listeners, namely IRtmServiceEventHandler
and IChannelEventHandler
, respectively. You must ensure that lifecycles of these listeners are longer than their objects.
(Objective-C SDK before v1.4.1) The lifecycle of the AgoraRtmChannel
object must be longer than that of the AgoraRtmKit
object; otherwise, the AgoraRtmKit
object may use the released AgoraRtmChannel
object, causing your app to crash.
Each callback of an RTM client instance runs in the same thread. A callback starts to execute when the previous callback finishes executing. If the previous callback takes too much time to execute, the callback cannot execute in time, and the queue of callbacks keeps growing.
(All SDKs) Agora recommends that you execute callbacks in time and try to reduce the execution time of callbacks. Otherwise, the callbacks that follow may be blocked or lost.
(Linux C++ /Linux Java SDK) The RTM Linux C++ / Linux Java server SDK does not block the SIGPIPE signal. You need to choose whether to block the SIGPIPE signal based on your use case. Generally, you need to block this signal. Otherwise, the client process exits by default after receiving the signal.
AgoraRtmAreaCode
AGORA_SDK_BOTH_RTM_AND_RTC
macro.AgoraRtmKit_swift.h
file in the SDK package.You need to follow the "first in, last out" stack operation sequence when initializing and destroying RTC and RTM SDK, that is, the SDK which is initialized later is destroyed first, for example:
RTC initialization → RTM initialization → RTM destruction → RTC destruction
or
RTM initialization → RTC initialization → RTC destruction → RTM destruction