Skip to main content

Integration best practice

An Signaling 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 the Signaling 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:


_53
// C++
_53
// Monitor the callback for token expiration
_53
class MyHandler : public IRtmServiceEventHandler {
_53
public:
_53
void onRenewTokenResult(const char* token, RENEW_TOKEN_ERR_CODE errorCode)
_53
{
_53
if (errorCode == RENEW_TOKEN_ERR_OK) {
_53
token_ = errorCode;
_53
}
_53
else {
_53
token_ = "";
_53
}
_53
}
_53
_53
void setToken(const std::string& token) {
_53
token_ = token;
_53
}
_53
_53
std::string getNewToken()
_53
{
_53
return token_;
_53
}
_53
private:
_53
std::string token_;
_53
};
_53
_53
// Get the token generated from the server and update the token for the SDK
_53
void renewTokenDemoCode() {
_53
auto client = createRtmService();
_53
std::string appId = "";
_53
std::string token = "";
_53
std::string userId = "";
_53
bool stopped = false;
_53
MyHandler handler;
_53
handler.setToken(token);
_53
client->initialize("appId", &handler);
_53
client->login(token.c_str(), userId.c_str());
_53
// Wait for login success
_53
sleep(10);
_53
_53
// Token Update token in a single thread
_53
while(!stopped) {
_53
// Update token every hour
_53
sleep(60 * 60);
_53
// Error handling
_53
if (handler.getNewToken().empty()) {
_53
break;
_53
}
_53
client->renewToken(handler.getNewToken().c_str());
_53
}
_53
client->logout();
_53
client->release();
_53
}

Manage your resources

Release unneeded resources in time

(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 Signaling client objects and channel objects.

Avoid accessing released resources

(All SDKs) If you have released the Signaling client object, Agora recommends that you do not access the related resources. Also, you cannot access the RtmCallManager object after releasing the Signaling client object.

Avoid releasing a channel object when it is in a callback of the channel 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.

Manage the lifecycle of resources

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

Avoid blocked callbacks

Each callback of an Signaling 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.

  • For the Signaling Native SDK, if the queue size reaches a certain limit, additional callbacks are discarded.

  • For the Signaling Web SDK, the queue size does not have a limit, but a long callback queue may cause performance issues.

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

Handle the SIGPIPE signal

*(Linux C /Linux Java SDK)* The Signaling 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.

When you are also using the Video SDK

Handle the naming conflict of AgoraRtmAreaCode

  • (C++ SDK, v1.4.2 or later ) Use the AGORA_SDK_BOTH_RTM_AND_RTC macro.

  • (Objective-C SDK version 1.4.3 and later) Whether your development language is Objective-C or Swift, Agora recommends that you use the AgoraRtmKit_swift.h file in the SDK package.

The sequence of SDK initialization and destruction

You need to follow the "first in, last out" stack operation sequence when initializing and destroying Video and Signaling SDK, that is, the SDK which is initialized later is destroyed first, for example:

Video SDK initialization → Signaling initialization → Signaling destruction → Video SDK destruction or Signaling initialization → Video SDK initialization → Video SDK destruction → Signaling destruction

Page Content