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.
AgoraRtmAreaCodeAGORA_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