LiveRoomManager.ets 7.04 KB
import {
  ChatroomDestroyType,
  ChatroomJoinedInfo,
  ChatroomStatusListener, ConnectionStatus, EngineError, IMEngine, InitOption,
  Message,
  ReceivedInfo} from '@rongcloud/imlib'
import { SpConstants } from 'wdConstant/Index'
import { CrptoUtils, DeviceUtil, EmitterEventId, EmitterUtils, Logger, SPHelper } from 'wdKit/Index'
import { HostEnum, HostManager, HttpBizUtil, HttpUrlUtils, HttpUtils, ResponseDTO } from 'wdNetwork/Index'
import { Context } from '@kit.AbilityKit';
import { LiveRoomBaseInfo } from './LiveRoomBaseInfo'
import { LiveRoom } from './LiveRoom'

const TAG = "LiveRoomManager"

export class LiveRoomManager {

  private static roomManager: LiveRoomManager

  private static RONGYUN_IM_APPKEY = "k51hidwqk50jb"
  private static RONGYUN_IM_APPKEY_TEST = "m7ua80gbm7yim"

  private hasInited: boolean = false
  public gotContextFunc?: () => Context = undefined

  private imTokenInfo?: string = undefined
  private connectRoomBaseInfo?: LiveRoomBaseInfo
  private connectedRoom?: LiveRoom

  /// 连接成功回调
  onConnectedRoom?:(room: LiveRoom) => void

  private constructor() {
  }

  public static sharedManager() {
    if (!LiveRoomManager.roomManager) {
      LiveRoomManager.roomManager = new LiveRoomManager()
    }
    LiveRoomManager.roomManager.checkToInitManager()
    return LiveRoomManager.roomManager
  }

  public connectLiveRoomWith(baseInfo: LiveRoomBaseInfo) {
    this.connectRoomBaseInfo = baseInfo
    if (this.imTokenInfo) {
      this.connectWithIMToken(this.imTokenInfo)
      return
    }
    this.fetchIMToken().then((token: string) => {
      this.imTokenInfo = token;
      this.connectWithIMToken(token)
    })
  }

  public disconnect() {
    this.connectedRoom?.exitRoom()
    this.connectedRoom = undefined
    IMEngine.getInstance().disconnect(true)
  }





  private checkToInitManager() {
    if (this.hasInited) {
      return
    }
    if (this.gotContextFunc) {
      let initOption = new InitOption();
      IMEngine.getInstance().init(this.gotContextFunc(), this.getAppKey(), initOption);
      this.listenStatus()
      this.hasInited = true
    }
  }

  private listenStatus() {
    EmitterUtils.receiveEvent(EmitterEventId.FORCE_USER_LOGIN_OUT, () => {
      this.imTokenInfo = undefined
      IMEngine.getInstance().disconnect(true)
    })

    IMEngine.getInstance().setConnectionStatusListener((status: ConnectionStatus) => {
      switch (status) {
        case ConnectionStatus.Connecting: {
          Logger.debug(TAG, "ConnectionStatus => 开始连接, 连接中....")
        } break
        case ConnectionStatus.Connected: {
          Logger.debug(TAG, "ConnectionStatus => 链接成功")
          this.processConnected()
        } break
        case ConnectionStatus.DisconnectNetworkUnavailable: {
          Logger.debug(TAG, "ConnectionStatus => 连接异常,SDK 会做好自动重连,开发者无须处理")
        } break
        case ConnectionStatus.DisconnectUserKicked: {
          Logger.debug(TAG, "ConnectionStatus => 当前用户在其他设备上登录,此设备被踢下线")
        } break
        case ConnectionStatus.DisconnectConnectionTimeout: {
          Logger.debug(TAG, "ConnectionStatus => 链接超时")
        } break
        case ConnectionStatus.DisconnectUserLogout: {
          Logger.debug(TAG, "ConnectionStatus => 退出连接")
        } break
        case ConnectionStatus.DisconnectTokenIncorrect: {
          Logger.debug(TAG, "ConnectionStatus => token无效,请检查AppKey配置,或者token过期,需要重新获取token")
        } break
        case ConnectionStatus.DisconnectTokenExpired: {
          Logger.debug(TAG, "ConnectionStatus => token过期,需要重新获取token")
        } break
        default : {
          Logger.debug(TAG, "ConnectionStatus => 其他状态:" + status)
        } break
      }
    })
  }

  private connectWithIMToken(token: string) {
    Logger.debug(TAG, "连接开始,IM Token:" + token)
    const timeout = 5
    IMEngine.getInstance().connect(token, timeout).then(result => {
      if (EngineError.Success === result.code) {
        // 连接成功
        let userId = result.userId;
        Logger.debug(TAG, "连接成功:" + userId)
        return
      }
      if (EngineError.ConnectionExists === result.code) {
        Logger.debug(TAG, "连接已存在")
        this.processConnected()
        return
      }
      Logger.debug(TAG, "连接结果:" + result.code)
    });
  }

  private processConnected() {
    this.connectedRoom = new LiveRoom(this.connectRoomBaseInfo)

    // let listener: ChatroomStatusListener = {
    //   onChatroomJoining(roomId: string): void {
    //     Logger.debug(TAG, `onChatroomJoining roomId: ${roomId}`);
    //     LiveRoomManager.sharedManager().connectedRoom?.onChatroomJoining(roomId)
    //   },
    //
    //   onChatroomJoined(roomId: string, info: ChatroomJoinedInfo): void {
    //     Logger.debug(TAG, `onChatroomJoining roomId: ${roomId}`);
    //     LiveRoomManager.sharedManager().connectedRoom?.onChatroomJoined(roomId, info)
    //   },
    //
    //   onChatroomJoinFailed(roomId: string, code: EngineError): void {
    //     Logger.debug(TAG, `onChatroomJoining roomId: ${roomId}`);
    //     LiveRoomManager.sharedManager().connectedRoom?.onChatroomJoinFailed(roomId, code)
    //   },
    //
    //   onChatroomQuited(roomId: string): void {
    //     Logger.debug(TAG, `onChatroomJoining roomId: ${roomId}`);
    //     LiveRoomManager.sharedManager().connectedRoom?.onChatroomQuited(roomId)
    //   },
    //
    //   onChatroomDestroyed(roomId: string, type: ChatroomDestroyType): void {
    //     Logger.debug(TAG, `onChatroomJoining roomId: ${roomId}`);
    //     LiveRoomManager.sharedManager().connectedRoom?.onChatroomDestroyed(roomId, type)
    //   },
    // }
    IMEngine.getInstance().setChatroomStatusListener(this.connectedRoom);
    IMEngine.getInstance().setMessageReceivedListener(this.connectedRoom.onMessage.bind(this.connectedRoom));
    if (this.onConnectedRoom) {
      this.onConnectedRoom(this.connectedRoom)
    }
  }

  private fetchIMToken() {
    return new Promise<string>(async (success, fail) => {

      let userId = HttpUtils.getUserId()
      if (userId.length == 0) {
        const deviceId = DeviceUtil.clientId()
        userId = await CrptoUtils.md5(deviceId)
      }
      let url = HttpUrlUtils.getLiveIMToken() + `?userId=${userId}&userName=${userId}`

      HttpBizUtil.get<ResponseDTO<string>>(url).then((data: ResponseDTO<string>) => {
        if (data.data) {
          success(data.data)
        } else {
          fail(data.message)
        }
      }).catch((error: Error) => {
        fail(error.message)
      })
    })
  }

  private getAppKey() {
    const appKey = SPHelper.default.getSync(SpConstants.ROMGYUN_IM_APPKEY, "") as string
    if (appKey.length > 0) {
      return appKey
    }
    const isOnlineEnv = HostManager.getHost() === HostEnum.HOST_PRODUCT
    return isOnlineEnv ? LiveRoomManager.RONGYUN_IM_APPKEY : LiveRoomManager.RONGYUN_IM_APPKEY_TEST
  }
}

interface LiveIMToken {
  // 连接IM的token
  refreshToken: string

  //token过期时间
  deadline: number
}