ConferApe.js 13.4 KB
// //////////////////////////////////////////////////////////////////////////////
//
//  Copyright (C) 2016-present  All Rights Reserved.
//  Licensed under the Apache License, Version 2.0 (the "License");
//  http://www.apache.org/licenses/LICENSE-2.0
//
//  Github Home: https://github.com/AlexWang1987
//  Author: AlexWang
//  Date: 2016-08-22 09:57:12
//  QQ Email: 1669499355@qq.com
//  Last Modified time: 2016-09-07 16:16:35
//  Description: LiveClass-ConferApe
//
// //////////////////////////////////////////////////////////////////////////////

import Ape from './Ape';
import ApeConsts from './ApeConsts';
import MessageTypes from 'MessageTypes';
import pdu from 'pdus';
import { Zlib } from 'zlibjs/bin/zlib.min';
import UTF8 from 'utf-8';
import Loger from 'Loger';
import GlobalConfig from 'GlobalConfig';
import EngineUtils from 'EngineUtils';

let loger = Loger.getLoger('ConferApe');
let itemIdx=0;//table插入新数据的计数id,目前用时间戳
class ConferApe extends Ape {
  constructor() {
    super(
      ApeConsts.CONFERENCE_SESSION_ID,
      ApeConsts.CONFERENCE_SESSION_NAME,
      ApeConsts.CONFERENCE_SESSION_TAG
    );

    // Attribures
    this.hostNodeId = -1;//主持人的nodeId
                          //    用户的身份,5种类型:
                          //    host(主持人/老师)
                          //    presenter(主讲人)
                          //    assistant(助教)
                          //    normal(普通角色/学生)
                          //    record(暂时没用.
                          //    默认值: normal
    this.hostUserId = '';//主持人的 第三方userId
    this.rosters = {};//用户列表
    this.activeDocId =0;//当前激活的文档ID
    this.activeDocCurPage=1;//当前激活的文档的当前页

    // Ape Models
    this.registerKey(this._session_id, this._session_name, this._session_tag, new ArrayBuffer);

    this.registerObj(pdu.RCPDU_REG_REGISTER_ROSTER, ApeConsts.CONFERENCE_OBJ_ROSTER_ID,
      ApeConsts.CONFERENCE_OBJ_ROSTER_NAME, ApeConsts.CONFERENCE_OBJ_ROSTER_TAG, 0, new ArrayBuffer);

    this.registerObj(pdu.RCPDU_REG_REGISTER_QUEUE, ApeConsts.CONFERENCE_OBJ_QUEUE_ID,
      ApeConsts.CONFERENCE_OBJ_QUEUE_NAME, ApeConsts.CONFERENCE_OBJ_QUEUE_TAG, 0, new ArrayBuffer);

    this.registerObj(pdu.RCPDU_REG_REGISTER_TABLE, ApeConsts.CONFERENCE_OBJ_TABLE_ID,
      ApeConsts.CONFERENCE_OBJ_TABLE_NAME, ApeConsts.CONFERENCE_OBJ_TABLE_TAG, 0, new ArrayBuffer);

    this.registerObj(pdu.RCPDU_REG_REGISTER_COUNTER, ApeConsts.CONFERENCE_OBJ_COUNTER_ID,
      ApeConsts.CONFERENCE_OBJ_COUNTER_NAME, ApeConsts.CONFERENCE_OBJ_COUNTER_TAG, 0, new ArrayBuffer);

    this.on(pdu.RCPDU_SESSION_JOIN_RESPONSE, this._joinSessionHandler.bind(this));

  }

  _joinSessionHandler(_data) {
    let nodeInfoRecordPdu = this.mcu.mcuClassInfo.self;
    loger.log("_joinSessionHandler nodeInfoRecordPdu=",nodeInfoRecordPdu);
    let userDataPdu = new pdu['RCNodeInfoUserDataPdu'];
    userDataPdu.qq = '';
    userDataPdu.skype = '';
    userDataPdu.mobile = '';

    nodeInfoRecordPdu.userData = userDataPdu.toArrayBuffer();
    nodeInfoRecordPdu.deviceType = 3;//设备类型

    let item = new pdu['RCRegistryRosterItemPdu'];
    item.nodeId = nodeInfoRecordPdu.nodeId;
    item.nodeData = nodeInfoRecordPdu.toArrayBuffer();

    let rosterUpdateItem = new pdu['RCRegistryRosterUpdateItemPdu'];
    rosterUpdateItem.type = pdu.RCPDU_REG_ROSTER_UPDATE_PDU;
    rosterUpdateItem.items.push(item);

    let updateObjPdu = new pdu['RCRegistryUpdateObjPdu'];
    updateObjPdu.objId = ApeConsts.CONFERENCE_OBJ_ROSTER_ID;
    updateObjPdu.subType = rosterUpdateItem.type;
    updateObjPdu.userData = rosterUpdateItem.toArrayBuffer();

    //同步
    let adapterItemPdu = new pdu['RCAdapterItemPdu'];
    adapterItemPdu.type = pdu.RCPDU_REG_UPDATE_OBJ;
    adapterItemPdu.itemData = updateObjPdu.toArrayBuffer();

    let adapterPdu = new pdu['RCAdapterPdu'];
    adapterPdu.type = pdu.RCPDU_REG_ADAPTER;
    adapterPdu.item.push(adapterItemPdu);

    this.sendUniform(adapterPdu, true);

  }

  //主动离开会议,发送通知到服务器
  leaveClass(){
    let nodeInfoRecordPdu = this.mcu.mcuClassInfo.self;
    let userDataPdu = new pdu['RCNodeInfoUserDataPdu'];
    userDataPdu.qq = '';
    userDataPdu.skype = '';
    userDataPdu.mobile = '';

    nodeInfoRecordPdu.userData = userDataPdu.toArrayBuffer();
    nodeInfoRecordPdu.deviceType = 3;

    let item = new pdu['RCRegistryRosterItemPdu'];
    item.nodeId = nodeInfoRecordPdu.nodeId;
    item.nodeData = nodeInfoRecordPdu.toArrayBuffer();

    let rosterUpdateItem = new pdu['RCRegistryRosterDeleteItemPdu'];
    rosterUpdateItem.type = pdu.RCPDU_REG_ROSTER_DELETE_PDU;
    rosterUpdateItem.nodeId=GlobalConfig.nodeId;

    let updateObjPdu = new pdu['RCRegistryUpdateObjPdu'];
    updateObjPdu.objId = ApeConsts.CONFERENCE_OBJ_ROSTER_ID;
    updateObjPdu.subType = rosterUpdateItem.type;
    updateObjPdu.userData = rosterUpdateItem.toArrayBuffer();

    let adapterItemPdu = new pdu['RCAdapterItemPdu'];
    adapterItemPdu.type = pdu.RCPDU_REG_UPDATE_OBJ;
    adapterItemPdu.itemData = updateObjPdu.toArrayBuffer();

    let adapterPdu = new pdu['RCAdapterPdu'];
    adapterPdu.type = pdu.RCPDU_REG_ADAPTER;
    adapterPdu.item.push(adapterItemPdu);

    this.sendUniform(adapterPdu, true);
  }

  //更新会议信息
  sendUpdaterClassInfo(_param){
    loger.log('sendUpdaterClassInfo----------');
    if(_param==null||EngineUtils.isEmptyObject(_param)){
      loger.log('sendUpdaterClassInfo,参数错误');
      this._emit(MessageTypes.MCU_ERROR,MessageTypes.ERR_APE_INTERFACE_PARAM_WRONG);
      return ;
    }
    itemIdx=_param.itemIdx;
    let whiteBoardModelPdu = this.packPdu(_param,itemIdx);
    console.log(whiteBoardModelPdu);

    if(whiteBoardModelPdu==null){
      loger.log('sendUpdaterClassInfo,参数错误');
      this._emit(MessageTypes.MCU_ERROR,MessageTypes.ERR_APE_INTERFACE_PARAM_WRONG);
      return ;
    }

    let tableItemPdu = new pdu['RCRegistryTableItemPdu'];
    tableItemPdu.itemIdx=itemIdx;
    tableItemPdu.owner = 0;//收到flash的是这个值,不清楚先写固定
    tableItemPdu.registerObjId=ApeConsts.CONFERENCE_OBJ_TABLE_ID;
    tableItemPdu.itemData =whiteBoardModelPdu.toArrayBuffer();


    //updater
    let whiteBoardUpdateItem = new pdu['RCRegistryTableUpdateItemPdu'];
    //optional RCPduType_E type = 1 [default = RCPDU_REG_TABLE_UPDATE_PDU];
    //repeated RCRegistryTableItemPdu items = 2;
    whiteBoardUpdateItem.type = pdu.RCPDU_REG_TABLE_UPDATE_PDU;//
    whiteBoardUpdateItem.items.push(tableItemPdu);


    let updateObjPdu = new pdu['RCRegistryUpdateObjPdu'];
    updateObjPdu.objId = ApeConsts.CONFERENCE_OBJ_TABLE_ID;
    updateObjPdu.subType = whiteBoardUpdateItem.type;
    updateObjPdu.userData = whiteBoardUpdateItem.toArrayBuffer();

    //同步
    let adapterItemPdu = new pdu['RCAdapterItemPdu'];
    adapterItemPdu.type = pdu.RCPDU_REG_UPDATE_OBJ;
    adapterItemPdu.itemData = updateObjPdu.toArrayBuffer();

    let adapterPdu = new pdu['RCAdapterPdu'];
    adapterPdu.type = pdu.RCPDU_REG_ADAPTER;
    adapterPdu.item.push(adapterItemPdu);

    console.log("会议发送更新数据============");
    this.sendUniform(adapterPdu,true);
  }

  //更新会议状态
  sendUpdaterClassStatus(_param){
    loger.log('sendUpdaterClassStatus----------');
    if(_param==null||EngineUtils.isEmptyObject(_param)){
      loger.log('sendUpdaterClassInfo,参数错误');
      this._emit(MessageTypes.MCU_ERROR,MessageTypes.ERR_APE_INTERFACE_PARAM_WRONG);
      return ;
    }
    itemIdx=_param.itemIdx;
    let whiteBoardModelPdu = this.packPdu(_param,itemIdx);
    console.log(whiteBoardModelPdu);

    if(whiteBoardModelPdu==null){
      loger.log('sendUpdaterClassInfo,参数错误');
      this._emit(MessageTypes.MCU_ERROR,MessageTypes.ERR_APE_INTERFACE_PARAM_WRONG);
      return ;
    }

    let tableItemPdu = new pdu['RCRegistryTableItemPdu'];
    tableItemPdu.itemIdx=itemIdx;
    tableItemPdu.owner = 0;//收到flash的是这个值,不清楚先写固定
    tableItemPdu.registerObjId=ApeConsts.CONFERENCE_OBJ_TABLE_ID;
    tableItemPdu.itemData =whiteBoardModelPdu.toArrayBuffer();


    //updater
    let whiteBoardUpdateItem = new pdu['RCRegistryTableUpdateItemPdu'];
    //optional RCPduType_E type = 1 [default = RCPDU_REG_TABLE_UPDATE_PDU];
    //repeated RCRegistryTableItemPdu items = 2;
    whiteBoardUpdateItem.type = pdu.RCPDU_REG_TABLE_UPDATE_PDU;//
    whiteBoardUpdateItem.items.push(tableItemPdu);


    let updateObjPdu = new pdu['RCRegistryUpdateObjPdu'];
    updateObjPdu.objId = ApeConsts.CONFERENCE_OBJ_TABLE_ID;
    updateObjPdu.subType = whiteBoardUpdateItem.type;
    updateObjPdu.userData = whiteBoardUpdateItem.toArrayBuffer();

    //同步
    let adapterItemPdu = new pdu['RCAdapterItemPdu'];
    adapterItemPdu.type = pdu.RCPDU_REG_UPDATE_OBJ;
    adapterItemPdu.itemData = updateObjPdu.toArrayBuffer();

    let adapterPdu = new pdu['RCAdapterPdu'];
    adapterPdu.type = pdu.RCPDU_REG_ADAPTER;
    adapterPdu.item.push(adapterItemPdu);

    console.log("会议发送更新数据111============");
    this.sendUniform(adapterPdu,true);
  }

  ///////白板数据的封包和解包/////////////////////////////////////////
  packPdu(_param,_itemIdx){
    loger.log("会议===packPdu ");
    //验证坐标点集合数组是否合法
    if(_param==null||_itemIdx==null){
      this._emit(MessageTypes.MCU_ERROR,MessageTypes.ERR_APE_INTERFACE_PARAM_WRONG);
      return null;
    }

    /*
     optional uint32 class_status= 1;//当前课堂状态 //0:未开始,1,开始,2,暂停
     optional string class_timestamp= 2;//目前用这个变量来记录时间 flash用的这个
     optional item_idx=3;
     optional from=4;
  */
    //判断type类型,根据type设置不同的参数
    let modelPdu =new pdu['RCClassSendDataModelPdu'];
    modelPdu.itemIdx=_itemIdx;
    modelPdu.owner=GlobalConfig.nodeId;
    modelPdu.from=GlobalConfig.nodeId;
    modelPdu.classStatus  =2;
    modelPdu.classTimestamp=32532532;

    console.log(modelPdu);
    return modelPdu;
  }

  unPackPdu(owner, itemIdx,itemData){
    loger.log("会议===unPackPdu ");
    if(owner==null||itemIdx==null||itemData==null){
      this._emit(MessageTypes.MCU_ERROR,MessageTypes.ERR_APE_INTERFACE_PARAM_WRONG);
      return null;
    }

    try{
      let docModelPdu= pdu['RCClassSendDataModelPdu'].decode(itemData);
      return docModelPdu;
    }catch (err){
      loger.log("会议收到数据 unPackPdu Pdu解析错误,itemIdx="+itemIdx+"  err:"+err.message);
    }
    return null;
  }


  /////收到消息处理/////////////////////////////////////////////////////////////////////////////////
  tableUpdateHandler(owner, itemIdx, itemData) {
    try {
      let model=this.unPackPdu(owner, itemIdx,itemData);
      loger.log('tableUpdateHandler',model);
    } catch (e) {
      loger.warn('ConferApe table update got exception.   itemIdx',itemIdx);
    }

/*    try {
      let tabUpdatePdu = pdu["RCTabUpdateDataRequestPdu"].decode(itemData);
      const uncompressedBytes = new Zlib.Inflate(tabUpdatePdu.action.compact().view).decompress();
      let tabInfo = UTF8.getStringFromBytes(uncompressedBytes);
      let tabTypeMatches = tabInfo.match(/<TabType>(.+)<\/TabType>/);
      loger.log("更新列表数据 tableUpdateHandler","owner:"+owner, "itemIdx:"+itemIdx,"tabInfo:",tabInfo);
      if (tabTypeMatches.length > 1 && tabTypeMatches[1] == 'show.docsharing') {
        if (tabInfo.match(/<visible>(.+)<\/visible>/)[1] == 'true') {
          this.activeDocId = tabInfo.match(/<TabID>(.+)<\/TabID>/)[1];
          this._emit(MessageTypes.DOC_SWITCH, this.activeDocId);
        }
      }
    } catch (e) {
      loger.warn('ConferApe table update got exception.   itemIdx',itemIdx);
    }*/
  }


  rosterInsertHandler(nodeId, nodeData) {
    if(GlobalConfig.nodeId==nodeId){
      loger.log("自己加入 rosterInsertHandler");
    }else {
      loger.log("有人加入 rosterInsertHandler");
      this.rosterUpdateHandler(nodeId, nodeData);
    }
  }

  //更新人员列表数据
  rosterUpdateHandler(nodeId, nodeData) {
    if (nodeData.role === ApeConsts.NR_MASTER ||
      nodeData.role === ApeConsts.NR_SLAVE) {
      this.hostNodeId = nodeData.nodeId;
      this.hostUserId = nodeData.userId;
    }
    if (nodeData.role === ApeConsts.NR_NORMAL &&
      this.hostNodeId === nodeData.nodeId) {
      this.hostNodeId = -1;
      this.hostUserId = '';
    }
    let rosterExists = this.rosters[nodeId];
    this.rosters[nodeId] = nodeData;
    if (!rosterExists) {
      let userDataObj=pdu['RCNodeInfoUserDataPdu'].decode(nodeData.userData);
      let newNodeData=nodeData;
      newNodeData.userData=userDataObj;
      loger.log("更新人员列表数据 rosterUpdateHandler",{"nodeId":nodeId});
      this._emit(MessageTypes.CLASS_INSERT_ROSTER, {"nodeId":nodeId,"nodeData":newNodeData});
      this.emitRosterChange();
    }else {
      //loger.log("更新人员列表数据,rosterExists已经存在",rosterExists);
    }
  }

  //删除用户
  rosterDelHandler(nodeId) {
    if(GlobalConfig.nodeId==nodeId){
      loger.log("自己离开 rosterDelHandler");
      // 自己退出
      this._emit(MessageTypes.CLASS_EXIT);
    }else {
      loger.log("有人离开 rosterDelHandler");
      delete this.rosters[nodeId];
      this._emit(MessageTypes.CLASS_DELETE_ROSTER, {"nodeId":nodeId});
      this.emitRosterChange();
    }
  }

  //广播当前的人数
  emitRosterChange() {
    this._emit(MessageTypes.CLASS_SHOW_ROSTER_NUM, Object.keys(this.rosters).length);
  }
}

export default ConferApe;