Windows

更新时间:2025-04-02 06:37:33

介绍Windows端如何接入实时消息(Real-Time Messaging,RTM)功能。

简介

实时消息具有低延时、高并发、高可靠性等特点,可用于直播聊天互动、语聊房等场景。

DingRTC的实时消息能力依托于会议,使用前需先成功入会。

相关概念

会话(Session):实时消息会话,由sessionId唯一标识。Session支持join/leave/close操作,收发实时消息前,需先创建Session并加入。DingRTC支持创建多个不同sessionId的会话,各Session之间互不干扰。

广播消息:对Session里的所有其他成员发送消息。

点对点消息:Session里的指定UserID的用户发送消息。

集成方法

  1. 入会前,设置好RTM的消息监听:

    先定义RTM的回调监听类:

    class MyEngineEventListerner : public ding::rtc::RtcEngineEventListener,
      public ding::rtc::RtmEventListener
    {
    public:
      ... 实现ding::rtc::RtcEngineEventListener 定义的接口
      // implement ding::rtc::RtmEventListener
      void OnRtmServerStateChanged(
        ding::rtc::RtmServerState state, int reason) override
      {
        这个接口一定要实现。只有当state == ding::rtc::RtmServerState::Available
        之后才能用RTM功能
    
        RtmInfo *rtm_info = &GetGlobalContext()->rtm_info_;
    
        if (state == ding::rtc::RtmServerState::Available) {
          rtm功能可以使用
        }
        else {
          rtm功能暂时不可以使用
        }
      }
      void OnJoinSessionResult(
        const ding::rtc::String &sessionId, int result) override
      {
        对应JoinSession的回调,表示加入session成功还是失败
      }
      void OnLeaveSessionResult(
        const ding::rtc::String &sessionId, int result) override
      {
      }
      void OnCloseSessionResult(
        const ding::rtc::String &sessionId, int result) override
      {
      }
      void OnRemovedFromSession(
        const ding::rtc::String &sessionId, int reason) override
      {
      }
      void OnSessionCreate(
        const ding::rtc::String &sessionId) override
      {
      }
      void OnSessionClose(
        const ding::rtc::String &sessionId) override
      {
      }
      void OnSessionRemoteUserJoin(
        const ding::rtc::String &sessionId,
        const ding::rtc::String &uid) override
      {
      }
      void OnSessionRemoteUserLeave(
        const ding::rtc::String &sessionId,
        const ding::rtc::String &uid) override
      {
      }
      void OnMessage(const ding::rtc::String &sessionId,
        const ding::rtc::String &fromUid, bool broadcast,
        const ding::rtc::RtmData &data) override
      {
        // 来自remote user发送的消息,在这里通知
      }
    };
    

    然后设置给engine:

    MyEngineEventListerner *mylistener = ...;
    ding::rtc::RtmClient *rtmclient = rtcengine->GetRtmClient();
    rtmclient->SetListener((ding::rtc::RtmEventListener *) mylistener);
    注意:这里用了类型强转,因为MyEngineEventListerner使用了c++多重继承。

  2. 入会后,在收到OnRtmServerStateChanged回调并且state == ding::rtc::RtmServerState::Available,可以使用rtm的功能了。首先,创建或者加入一个RTM Session:

    int rc = rtmclient->JoinSession(sessId);
    如果rc == 0,预期会收到OnJoinSessionResult回调,进一步确认加入是否成功。
    如果rc < 0,那么不会有OnJoinSessionResult回调。检查一下参数是不是有问题。
  3. 会中其他成员会收到有新的session被创建出来(通过MyEngineEventListerner::OnSessionCreate事件通知),加入该Session,代码和上面相同。

  4. 同一个Session中的成员可以互相发送实时消息。

    发送广播消息:

    ding::rtc::RtmData *d = new ding::rtc::RtmData;
    d->data = malloc(len);
    d->size = len;
    memcpy((uint8_t*)d->data, text, len);
    
    rc = rtmclient->BroadcastData(sessId, *d);
    处理返回值,如果是0,那么表示发送成功。其他错误码,见接口文档。
    if (rc != 0)
    {
      std::string sErr;
      switch (rc)
      {
      case ding::rtc::RtmErrorCode::RtmInnerError:
            sErr = "Internal error"; break;
      case ding::rtc::RtmErrorCode::RtmServiceNotReady:
            sErr = "Rtm service not ready"; break;
      case ding::rtc::RtmErrorCode::RtmMsgLengthExceed:
            sErr = "Length exceeds limitation"; break;
      case ding::rtc::RtmErrorCode::RtmMsgQueueFull:
            sErr = "Qps exceeds limitation"; break;
      case ding::rtc::RtmErrorCode::BadSessionState:
            sErr = "Session lost or not joined"; break;
      case ding::rtc::RtmErrorCode::RtmReceiverNotExist:
            sErr = "Remote user left session"; break;
      default:
            sErr = "Unknown error"; break;
      }
      std::wstring wErr = utf82utf16(sErr);
      MessageBox(wErr.c_str(), _T("Failed to send message"), MB_ICONHAND);
    }
    
    用完记得删除数据:
    free ((void *)d->data);
    delete d;
    

    发送点对点消息:

    代码和广播类似,不同的是指定了接收者的userid:
    rc = rtmclient->SendData(sessionId, remoteuid, *d);

    Session内的远端用户通过MyEngineEventListerner::OnMessage接收消息:

      void OnMessage(const ding::rtc::String &sessionId,
        const ding::rtc::String &fromUid, bool broadcast,
        const ding::rtc::RtmData &data) override
      {
        // 来自remote user发送的消息,在这里通知
      }
  5. 对于更复杂的应用,界面上维护Session的成员列表的,可以监听这些消息:

    void OnSessionRemoteUserJoin(const ding::rtc::String &sessionId,
      const ding::rtc::String &uid) override;
    void OnSessionRemoteUserLeave(const ding::rtc::String &sessionId,
      const ding::rtc::String &uid) override;
    以及频道级别的回调:
    virtual void OnRemoteUserOffLineNotify(const char *uid,
      ding::rtc::RtcEngineUserOfflineReason reason) override;

  6. 对于简单应用,入会时所有人加入一个default Session: JoinSession("default"); (在RtmServerState::Available之后)。后面就可以broadcast或者unicast消息了。

  7. 异常处理

    除了发送消息的返回值需要处理之外,还要监听和处理这些消息:

    某个原因被移除出Session:
    void OnRemovedFromSession(const ding::rtc::String &sessionId, int reason) override;
    Session被关闭了:
    void OnSessionClose(const ding::rtc::String &sessionId) override;

注意事项

  1. 离会时,SDK内部会清空所有Session信息,实时消息功能不再可用。

  2. 远端用户不调leaveSession直接leaveChannel,有可能收不到这个远端用户的onSessionRemoteUserLeave事件通知。应用层需要在收到他的onRemoteUserOffLineNotify事件通知后,主动将该用户从所有Session的成员列表里移除。

  • 本页导读 (0)
  • 简介
  • 相关概念
  • 集成方法
  • 注意事项
AI助理

点击开启售前

在线咨询服务

你好,我是AI助理

可以解答问题、推荐解决方案等