RTM SDK 最佳实践

最近更新时间:2021-03-18 11:04:19

本文包括集成 RTM SDK 时的最佳实践。

定时更新 Token

(所有 SDK) Token 的最长有效期是 24 小时。如果 Token 失效,且此时用户与 RTM 服务器的连接由于用户端网络或服务端故障断开,SDK 将无法自动恢复连接,因为自动重连会触发 Token expired 错误。此时你必须登出之后再登录才能恢复连接。

anyRTC 建议你定时(例如每小时)从服务端生成 Token 并调用 renewToken 方法更新 SDK 的 Token,保证 SDK 的 Token 一直处于有效状态。关于如何在服务端生成 Token,参考生成 RTM Token

下面的示例代码展示了如何定时更新 Token。

// C++
// 监听 Token 过期回调
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_;
};

// 获取服务端生成的 Token 并通过 renewToken 方法更新 SDK 的 Token
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());
  // 等待登录成功
  sleep(10);

  // 在单线程中更新 Token
  while(!stopped) {
    // 每小时更新一次
    sleep(60 * 60);
    // 错误处理
    if (handler.getNewToken().empty()) {
      break;
    }
    client->renewToken(handler.getNewToken().c_str());
  }
  client->logout();
  client->release();
}

合理进行资源管理

及时释放不需要的资源

(C++ SDK, Java SDK) 不及时释放创建的资源可能导致内存泄漏。虽然 Java 的 GC (Garbage Collection) 机制可以回收上层 Java 对象,但是 Java SDK 的底层 C++ API 仍然使用 Java 对象进行回调,因此会造成崩溃。

anyRTC 建议你主动调用 release 方法释放客户端对象和频道对象。

不要在频道对象的回调中释放回调

(C++ SDK, Java SDK, Objective-C SDK) 如果你在频道对象的回调方法中,调用 release 方法释放频道对象,由于回调方法会对对象加锁,release 方法会请求同一把锁,造成应用卡住。

注意管理资源的生命周期

(C++ SDK) 如果你为 IRtmService 对象和 IChannel 对象设置了相应的监听器,即 IRtmServiceEventHandler 和 IChannelEventHandler,你需要保证监听器的生命周期长于对象的生命周期。否则对象可能会调用已经释放的监听器,造成崩溃。

避免回调阻塞

(所有 SDK) anyRTC 建议你及时执行回调,并尽量减少回调的运行时间。否则可能会阻塞后面的回调,或造成回调丢失。

每一个 RTM 客户端实例的回调都是运行在同一个线程上的。后一个回调会等待前一个回调执行完成后再开始执行。 如果前一个回调的运行时间比较长,会使之后的回调不能及时触发,同时等待处理的回调队列越来越长。

  • 对于 RTM Native SDK,达到队列长度限制之后,额外的回调事件会被丢弃。
  • 对于 RTM Web SDK 和微信小程序 SDK,虽然队列长度没有限制,但是过长的回调队列会造成性能问题。