Web

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

简介

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

相关概念

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

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

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

集成方法

Web rtm sdk支持独立使用和配合 dingrtc web sdk 使用两种方式:

  • 独立使用:使用白板管理器实例加入频道,适合只使用rtm的情况

  • 配合 dingrtc 使用:与 dingrtc 实例共享频道链接,适合 dingrtc 和rtm一起使用的情况

下面提供集成示例,以ES6 语法为标准:

  1. 获取RTM实例并加入频道:

    // 独立使用
    import RTM from '@dingrtc/rtm';
    
    const rtm = new RTM();
    // 参考 https://help.aliyun.com/document_detail/2640080.html 开通 DingRTC 服务
    // 获取用户配置以加入频道
    await rtm.join({
      appId: '',
      userName: '',
      channel: '',
      uid: '',
      token: ''
    });
    
    // 配合 dingrtc 使用
    import DingRTC from 'dingrtc';
    import RTM from '@dingrtc/rtm';
    
    const client = DingRTC.createClient();
    
    const rtm = new RTM();
    // rtm和 rtc 共享同一个入会连接
    client.register(rtm);
    
    await client.join({
      appId: '',
      userName: '',
      channel: '',
      uid: '',
      token: '',
    });
  2. RTM实例设置回调监听:

    // 独立使用时关注,若与dingrtc 配合使用则无需关注
    rtm.on('connection-state-changed', (currState, prevState, reason) => {
      console.log(currState, prevState, reason)
    })
    rtm.on('message', (data) => {
      console.log(data)
    })
    // 监听rtm会话添加/移除事件
    rtm.on('session-add', (session) => {
      console.log(session)
    })
    rtm.on('session-remove', (session) => {
      console.log(session)
    })
    // 监听rtm会话成员进出事件
    rtm.on('session-user-join', (sessionId, uid) => {
      console.log(sessionId, uid)
    })
    rtm.on('session-user-left', (sessionId, uid) => {
      console.log(sessionId, uid)
    })
  3. 会话发起者创建并加入Session:

    await rtm.joinSession(sessionId); // Session不存在时调用joinSession会先创建Session然后加入
  4. 会中其他成员会收到session-add事件通知,然后加入相同Session:

    await rtm.joinSession(sessionId); // Session存在时调用joinSession直接加入
  5. 加入Session(如果Session有其他成员)或者是中途有其他成员加入Session,都会收到session-user-join事件通知。如有点对点发送实时消息的需求,需要应用层维护Session的成员列表:

    // 监听rtm会话成员进出事件
    rtm.on('session-user-join', (sessionId, uid) => {
        // addSessionUser方法由应用层实现,用来添加Session新加入的User。
        addSessionUser(sessionId, uid);
    })

    同时在别人离开Session时,会收到session-user-left事件通知,按需做好Session成员列表的维护:

    rtm.on('session-user-left', (sessionId, uid) => {
      // removeSessionUser方法由应用层实现,用来移除Session离开的User。
      removeSessionUser(sessionId, uid);
    })
  6. SDK支持收发UTF-8编码的字符串和二进制数据,Web端统一用Uint8Array数组作为参数来传递消息。 当前限制每秒最多60条消息,单条消息长度应不超过4KB,更长的消息可能会导致丢失。

    发送广播消息:

    const message = 'hello world';
    const encoder = new TextEncoder();
    const sessionId = 'xxxxxx';
    // 广播
    rtm.publish(sessionId, encoder.encode(message));

    发送点对点消息:

    const message = 'hello world';
    const encoder = new TextEncoder();
    // 点对点发布, 需要双方在同一个RTM会话内
    const otherUserId = 'user1';
    const sessionId = 'xxxxxx';
    rtm.publish(sessionId, encoder.encode(message), otherUserId);

    接收消息:

    // 监听远端消息发布事件
    rtm.on('message', (data) => {
      const {
        message, // 消息载体, Uint8Array格式
        uid, // 发布人的uid
        sessionId, // 消息归属的sessionId
        broadcast, // 消息是广播还是点对点发布
      } = data;
      console.log(decoder.decode(message))
    })
  7. 如果本端不再使用实时消息功能,可以离开Session:

    rtm.leaveSession(sessionId);

    离开Session后,将收不到该Session里其他成员发送的广播消息,该Session里其他成员也无法给您发送点对点消息。

  8. 如果不再使用某个Session,可以关闭Session:

    rtm.closeSession(sessionId);

    关闭Session后,Session的所有成员(包括自己)都会收到session-remove事件通知,该Session不再可用。

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