AlexWang

增加Cursor及同步

@@ -18,6 +18,7 @@ import VideoApe from 'apes/VideoApe'; @@ -18,6 +18,7 @@ import VideoApe from 'apes/VideoApe';
18 import AudioApe from 'apes/AudioApe'; 18 import AudioApe from 'apes/AudioApe';
19 import DocApe from 'apes/DocApe'; 19 import DocApe from 'apes/DocApe';
20 import WhiteBoardApe from 'apes/WhiteBoardApe'; 20 import WhiteBoardApe from 'apes/WhiteBoardApe';
  21 +import CursorApe from 'apes/CursorApe';
21 22
22 import EngineUtils from "EngineUtils"; 23 import EngineUtils from "EngineUtils";
23 import GlobalConfig from 'GlobalConfig'; 24 import GlobalConfig from 'GlobalConfig';
@@ -44,6 +45,7 @@ let _video_ape; @@ -44,6 +45,7 @@ let _video_ape;
44 let _audio_ape; 45 let _audio_ape;
45 let _doc_ape; 46 let _doc_ape;
46 let _whiteboard_ape; 47 let _whiteboard_ape;
  48 +let _cursor_ape;
47 let _recordPlayback; 49 let _recordPlayback;
48 let _mediaShareApe; 50 let _mediaShareApe;
49 let _questionApe; 51 let _questionApe;
@@ -126,6 +128,9 @@ export default class MessageEntrance extends Emiter { @@ -126,6 +128,9 @@ export default class MessageEntrance extends Emiter {
126 _whiteboard_ape = new WhiteBoardApe(); 128 _whiteboard_ape = new WhiteBoardApe();
127 _whiteboard_ape.on('*', (type, data) => this._emit(type, data)); 129 _whiteboard_ape.on('*', (type, data) => this._emit(type, data));
128 130
  131 + _cursor_ape = new CursorApe();
  132 + _cursor_ape.on('*', (type, data) => this._emit(type, data));
  133 +
129 _doc_ape = new DocApe(); 134 _doc_ape = new DocApe();
130 _doc_ape.on('*', (type, data) => this._emit(type, data)); 135 _doc_ape.on('*', (type, data) => this._emit(type, data));
131 _doc_ape.on(MessageTypes.DOC_UPDATE, this.docUpdateHandler.bind(this)); 136 _doc_ape.on(MessageTypes.DOC_UPDATE, this.docUpdateHandler.bind(this));
@@ -149,7 +154,7 @@ export default class MessageEntrance extends Emiter { @@ -149,7 +154,7 @@ export default class MessageEntrance extends Emiter {
149 this.sendCloseClass = this._sendCloseClass.bind(this); 154 this.sendCloseClass = this._sendCloseClass.bind(this);
150 this.changeHandUpStatus = this._changeHandUpStatus.bind(this); //自己切换举手状态 155 this.changeHandUpStatus = this._changeHandUpStatus.bind(this); //自己切换举手状态
151 this.controlHandUpStatus = this._controlHandUpStatus.bind(this); //控制别人的举手状态 156 this.controlHandUpStatus = this._controlHandUpStatus.bind(this); //控制别人的举手状态
152 - this.controlSilenceStatus = this.controlSilenceStatus.bind(this); //改变禁言状态 157 + this.controlSilenceStatus = this._controlSilenceStatus.bind(this); //改变禁言状态
153 158
154 this.sceneTableChange = this._sceneTableChange.bind(this); //控制别人的举手状态 159 this.sceneTableChange = this._sceneTableChange.bind(this); //控制别人的举手状态
155 160
@@ -189,6 +194,9 @@ export default class MessageEntrance extends Emiter { @@ -189,6 +194,9 @@ export default class MessageEntrance extends Emiter {
189 this.sendDeleteCurPageAnnotation = this._sendDeleteCurPageAnnotation.bind(this); //删除当前页的所有标注 194 this.sendDeleteCurPageAnnotation = this._sendDeleteCurPageAnnotation.bind(this); //删除当前页的所有标注
190 this.sendGotoPrev = this._sendGotoPrev.bind(this); //当前页撤销上一步 195 this.sendGotoPrev = this._sendGotoPrev.bind(this); //当前页撤销上一步
191 196
  197 + // CursorApe
  198 + this.sendInsertCursor = this._sendInsertCursor.bind(this); //添加鼠标同步
  199 +
192 //DocApe 200 //DocApe
193 this.sendDocumentUpload = this._sendDocumentUpload.bind(this); //上传文档 201 this.sendDocumentUpload = this._sendDocumentUpload.bind(this); //上传文档
194 this.sendDocumentSwitchDoc = this._sendDocumentSwitchDoc.bind(this); //切换文档 202 this.sendDocumentSwitchDoc = this._sendDocumentSwitchDoc.bind(this); //切换文档
@@ -1391,6 +1399,18 @@ export default class MessageEntrance extends Emiter { @@ -1391,6 +1399,18 @@ export default class MessageEntrance extends Emiter {
1391 } 1399 }
1392 } 1400 }
1393 1401
  1402 + //CursorApe
  1403 + // 添加鼠标同步
  1404 + _sendInsertCursor(_param) {
  1405 + if (!_mcu.connected) {
  1406 + loger.warn(GlobalConfig.getCurrentStatus());
  1407 + return;
  1408 + }
  1409 + if (_cursor_ape) {
  1410 + _cursor_ape.sendInsertCursor(_param);
  1411 + }
  1412 + }
  1413 +
1394 //删除当前页面上的所有标注 1414 //删除当前页面上的所有标注
1395 _sendDeleteCurPageAnnotation(_param) { 1415 _sendDeleteCurPageAnnotation(_param) {
1396 if (!_mcu.connected) { 1416 if (!_mcu.connected) {
@@ -132,6 +132,7 @@ class GlobalConfig { @@ -132,6 +132,7 @@ class GlobalConfig {
132 132
133 // 全局禁言状态 133 // 全局禁言状态
134 this.silence = data.silence || false; 134 this.silence = data.silence || false;
  135 +
135 // 自有禁言状态 136 // 自有禁言状态
136 this.selfSilence = data.selfSilence || ''; 137 this.selfSilence = data.selfSilence || '';
137 this.recordStatus = data.recordStatus || this.recordStatus; //当前录制状态 138 this.recordStatus = data.recordStatus || this.recordStatus; //当前录制状态
@@ -9,6 +9,9 @@ function MessageTypes() {} @@ -9,6 +9,9 @@ function MessageTypes() {}
9 MessageTypes.CLASS_INIT_SUCCESS = "class_init_success"; //'class.init.success';//初始化成功 9 MessageTypes.CLASS_INIT_SUCCESS = "class_init_success"; //'class.init.success';//初始化成功
10 //MessageTypes.CLASS_INIT_FAILED='class.init.failed';//初始化失败 10 //MessageTypes.CLASS_INIT_FAILED='class.init.failed';//初始化失败
11 11
  12 +// 鼠标更新事件
  13 +MessageTypes.CURSOR_UPDATE = 'cursor_update';
  14 +
12 //加入课堂相关事件定义 15 //加入课堂相关事件定义
13 MessageTypes.CLASS_JOIN_MCU_SUCCESS = "class_join_mcu_success" // 'join.mcu.success'; 16 MessageTypes.CLASS_JOIN_MCU_SUCCESS = "class_join_mcu_success" // 'join.mcu.success';
14 //MessageTypes.CLASS_JOIN_FAILED = 'join.class.failed'; 17 //MessageTypes.CLASS_JOIN_FAILED = 'join.class.failed';
@@ -140,6 +140,8 @@ ApeConsts.MEDIA_SESSION_ID = 19; @@ -140,6 +140,8 @@ ApeConsts.MEDIA_SESSION_ID = 19;
140 ApeConsts.SCREENSHARING_SESSION_ID = 20; 140 ApeConsts.SCREENSHARING_SESSION_ID = 20;
141 ApeConsts.POLL_SESSION_ID = 21; 141 ApeConsts.POLL_SESSION_ID = 21;
142 ApeConsts.QUESTION_SESSION_ID = 22; 142 ApeConsts.QUESTION_SESSION_ID = 22;
  143 +ApeConsts.CURSOR_SESSION_ID = 23;
  144 +
143 // defs for common channel id 145 // defs for common channel id
144 ApeConsts.BROADCAST_CHANNEL_ID = 0; 146 ApeConsts.BROADCAST_CHANNEL_ID = 0;
145 ApeConsts.CONFERENCE_CHANNEL_ID = ApeConsts.CONFERENCE_SESSION_ID; 147 ApeConsts.CONFERENCE_CHANNEL_ID = ApeConsts.CONFERENCE_SESSION_ID;
@@ -148,6 +150,7 @@ ApeConsts.GIFT_CHANNEL_ID = ApeConsts.GIFT_SESSION_ID; @@ -148,6 +150,7 @@ ApeConsts.GIFT_CHANNEL_ID = ApeConsts.GIFT_SESSION_ID;
148 ApeConsts.WEBSHARING_CHANNEL_ID = ApeConsts.WEBSHARING_SESSION_ID; 150 ApeConsts.WEBSHARING_CHANNEL_ID = ApeConsts.WEBSHARING_SESSION_ID;
149 ApeConsts.DOCSHARING_CHANNEL_ID = ApeConsts.DOCSHARING_SESSION_ID; 151 ApeConsts.DOCSHARING_CHANNEL_ID = ApeConsts.DOCSHARING_SESSION_ID;
150 ApeConsts.WHITEBOARD_CHANNEL_ID = ApeConsts.WHITEBOARD_SESSION_ID; 152 ApeConsts.WHITEBOARD_CHANNEL_ID = ApeConsts.WHITEBOARD_SESSION_ID;
  153 +ApeConsts.CURSOR_CHANNEL_ID = ApeConsts.CURSOR_SESSION_ID;
151 ApeConsts.MEDIA_CHANNEL_ID = ApeConsts.MEDIA_SESSION_ID; 154 ApeConsts.MEDIA_CHANNEL_ID = ApeConsts.MEDIA_SESSION_ID;
152 ApeConsts.SCREENSHARING_CHANNEL_ID = ApeConsts.SCREENSHARING_SESSION_ID; 155 ApeConsts.SCREENSHARING_CHANNEL_ID = ApeConsts.SCREENSHARING_SESSION_ID;
153 156
@@ -162,6 +165,7 @@ ApeConsts.VIDEO_SESSION_NAME = "video app"; @@ -162,6 +165,7 @@ ApeConsts.VIDEO_SESSION_NAME = "video app";
162 ApeConsts.WEBSHARING_SESSION_NAME = "web sharing app"; 165 ApeConsts.WEBSHARING_SESSION_NAME = "web sharing app";
163 ApeConsts.DOCSHARING_SESSION_NAME = "doc sharing app"; 166 ApeConsts.DOCSHARING_SESSION_NAME = "doc sharing app";
164 ApeConsts.WHITEBOARD_SESSION_NAME = "whiteboard app"; 167 ApeConsts.WHITEBOARD_SESSION_NAME = "whiteboard app";
  168 +ApeConsts.CURSOR_SESSION_NAME = "cursor app";
165 ApeConsts.MEDIA_SESSION_NAME = "media sharing app"; 169 ApeConsts.MEDIA_SESSION_NAME = "media sharing app";
166 ApeConsts.SCREENSHARING_SESSION_NAME = "screen sharing app"; 170 ApeConsts.SCREENSHARING_SESSION_NAME = "screen sharing app";
167 ApeConsts.QUESTION_SESSION_NAME = "question app"; 171 ApeConsts.QUESTION_SESSION_NAME = "question app";
@@ -175,6 +179,7 @@ ApeConsts.VIDEO_SESSION_TAG = "vid-tag"; @@ -175,6 +179,7 @@ ApeConsts.VIDEO_SESSION_TAG = "vid-tag";
175 ApeConsts.WEBSHARING_SESSION_TAG = "web-tag"; 179 ApeConsts.WEBSHARING_SESSION_TAG = "web-tag";
176 ApeConsts.DOCSHARING_SESSION_TAG = "doc-tag"; 180 ApeConsts.DOCSHARING_SESSION_TAG = "doc-tag";
177 ApeConsts.WHITEBOARD_SESSION_TAG = "wbd-tag"; 181 ApeConsts.WHITEBOARD_SESSION_TAG = "wbd-tag";
  182 +ApeConsts.CURSOR_SESSION_TAG = "cursor-tag";
178 ApeConsts.MEDIA_SESSION_TAG = "med-tag"; 183 ApeConsts.MEDIA_SESSION_TAG = "med-tag";
179 ApeConsts.SCREENSHARING_SESSION_TAG = "scr-tag"; 184 ApeConsts.SCREENSHARING_SESSION_TAG = "scr-tag";
180 ApeConsts.QUESTION_SESSION_TAG = "qst-tag"; 185 ApeConsts.QUESTION_SESSION_TAG = "qst-tag";
@@ -222,6 +227,11 @@ ApeConsts.WHITEBOARD_OBJ_TABLE_ID = ((ApeConsts.WHITEBOARD_SESSION_ID << 16) + 1 @@ -222,6 +227,11 @@ ApeConsts.WHITEBOARD_OBJ_TABLE_ID = ((ApeConsts.WHITEBOARD_SESSION_ID << 16) + 1
222 ApeConsts.WHITEBOARD_OBJ_TABLE_NAME = "wbd list"; 227 ApeConsts.WHITEBOARD_OBJ_TABLE_NAME = "wbd list";
223 ApeConsts.WHITEBOARD_OBJ_TABLE_TAG = "wbd list tag"; 228 ApeConsts.WHITEBOARD_OBJ_TABLE_TAG = "wbd list tag";
224 229
  230 +// cursor objects
  231 +ApeConsts.CURSOR_OBJ_TABLE_ID = ((ApeConsts.CURSOR_SESSION_ID << 16) + 1);
  232 +ApeConsts.CURSOR_OBJ_TABLE_NAME = "cursor list";
  233 +ApeConsts.CURSOR_OBJ_TABLE_TAG = "cursor list tag";
  234 +
225 // media sharing objects 235 // media sharing objects
226 ApeConsts.MEDIA_OBJ_TABLE_ID = ((ApeConsts.MEDIA_SESSION_ID << 16) + 1); 236 ApeConsts.MEDIA_OBJ_TABLE_ID = ((ApeConsts.MEDIA_SESSION_ID << 16) + 1);
227 ApeConsts.MEDIA_OBJ_TABLE_NAME = "med list"; 237 ApeConsts.MEDIA_OBJ_TABLE_NAME = "med list";
@@ -332,15 +332,10 @@ class ConferApe extends Ape { @@ -332,15 +332,10 @@ class ConferApe extends Ape {
332 } 332 }
333 333
334 // 全局禁言 334 // 全局禁言
335 - silenceClass(isSilence) { 335 + silenceClass(params) {
336 if (GlobalConfig.isHost) { 336 if (GlobalConfig.isHost) {
337 - GlobalConfig.silence = !!isSilence;  
338 -  
339 - //禁言状态改变  
340 - this._emit(MessageTypes.CLASS_SILENCE_CHANGE, GlobalConfig.silence);  
341 -  
342 //同步禁言状态 337 //同步禁言状态
343 - this.sendUpdaterClassStatusInfo(); 338 + this.sendUpdaterClassStatusInfo(params);
344 } else { 339 } else {
345 loger.warn('没有开始课堂的权限'); 340 loger.warn('没有开始课堂的权限');
346 } 341 }
@@ -670,11 +665,11 @@ class ConferApe extends Ape { @@ -670,11 +665,11 @@ class ConferApe extends Ape {
670 } 665 }
671 break; 666 break;
672 case ApeConsts.USER_ACTION_SILENCE_STATUS_CHANGE: 667 case ApeConsts.USER_ACTION_SILENCE_STATUS_CHANGE:
673 - let msgObj = null; 668 + let silenceMsg = null;
674 try { 669 try {
675 - msgObj = JSON.parse(chatMsg.message);  
676 - if (msgObj && msgObj.nodeId == GlobalConfig.nodeId) {  
677 - this.changeSilenceStatus(msgObj); 670 + silenceMsg = JSON.parse(chatMsg.message);
  671 + if (silenceMsg && silenceMsg.nodeId == GlobalConfig.nodeId) {
  672 + this.changeSilenceStatus(silenceMsg);
678 } 673 }
679 } catch (err) { 674 } catch (err) {
680 loger.warn('chatMsg->JSON数据解析失败'); 675 loger.warn('chatMsg->JSON数据解析失败');
@@ -971,7 +966,7 @@ class ConferApe extends Ape { @@ -971,7 +966,7 @@ class ConferApe extends Ape {
971 classStatusInfo.activeDocCurPage = GlobalConfig.activeDocCurPage; //当前激活的文档的当前页 966 classStatusInfo.activeDocCurPage = GlobalConfig.activeDocCurPage; //当前激活的文档的当前页
972 classStatusInfo.isStopAllPublishMedia = _param.isStopAllPublishMedia || false; 967 classStatusInfo.isStopAllPublishMedia = _param.isStopAllPublishMedia || false;
973 classStatusInfo.currentSceneTableId = GlobalConfig.currentSceneTableId; 968 classStatusInfo.currentSceneTableId = GlobalConfig.currentSceneTableId;
974 - classStatusInfo.silence = GlobalConfig.silence; 969 + classStatusInfo.silence = _param.silence || false;
975 //loger.log("classStatusInfo--->", classStatusInfo); 970 //loger.log("classStatusInfo--->", classStatusInfo);
976 971
977 /* 972 /*
  1 +// //////////////////////////////////////////////////////////////////////////////
  2 +//
  3 +// Copyright (C) 2016-present All Rights Reserved.
  4 +// Licensed under the Apache License, Version 2.0 (the "License");
  5 +// http://www.apache.org/licenses/LICENSE-2.0
  6 +//
  7 +// Github Home: https://github.com/AlexWang1987
  8 +// Author: AlexWang
  9 +// Date: 2016-08-26 17:36:20
  10 +// QQ Email: 1669499355@qq.com
  11 +// Last Modified time: 2017-06-22 11:47:29
  12 +// Description: LiveClass-CursorApe
  13 +//
  14 +// //////////////////////////////////////////////////////////////////////////////
  15 +
  16 +import Ape from './Ape';
  17 +import ApeConsts from './ApeConsts';
  18 +import pdu from 'pdus';
  19 +import Loger from 'Loger';
  20 +import MessageTypes from 'MessageTypes';
  21 +import GlobalConfig from 'GlobalConfig';
  22 +import EngineUtils from 'EngineUtils';
  23 +
  24 +let loger = Loger.getLoger('CursorApe');
  25 +
  26 +const DEFAULT_TYPE = 0; //鼠标
  27 +
  28 +class CursorApe extends Ape {
  29 + constructor() {
  30 + super(
  31 + ApeConsts.CURSOR_SESSION_ID,
  32 + ApeConsts.CURSOR_SESSION_NAME,
  33 + ApeConsts.CURSOR_SESSION_TAG
  34 + );
  35 +
  36 + //Ape Models
  37 + this.registerKey(this._session_id, this._session_name, this._session_tag, new ArrayBuffer);
  38 + this.registerObj(pdu.RCPDU_REG_REGISTER_TABLE, ApeConsts.CURSOR_OBJ_TABLE_ID,
  39 + ApeConsts.CURSOR_OBJ_TABLE_NAME, ApeConsts.CURSOR_OBJ_TABLE_TAG, 0, new ArrayBuffer);
  40 +
  41 + // ape listeners
  42 + this.on(pdu.RCPDU_SESSION_JOIN_RESPONSE, this._joinSessionHandler.bind(this));
  43 + }
  44 +
  45 + _joinSessionHandler(_data) {
  46 + loger.log("RCPDU_SESSION_JOIN_RESPONSE");
  47 + }
  48 +
  49 + // 添加鼠标
  50 + sendInsertCursor(_param) {
  51 + if (_param == null || EngineUtils.isEmptyObject(_param)) {
  52 + loger.warn('添加标注失败->参数错误->', _param);
  53 + this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_APE_INTERFACE_PARAM_WRONG);
  54 + return;
  55 + }
  56 +
  57 + let itemIdx = EngineUtils.creatSoleNumberFromTimestamp(); //创建时间戳,保证每条数据的唯一
  58 + let cursorModelPdu = this.packPdu(_param, itemIdx);
  59 + if (cursorModelPdu == null) {
  60 + loger.warn('添加标注失败-->参数错误->', _param);
  61 + this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_APE_INTERFACE_PARAM_WRONG);
  62 + return;
  63 + }
  64 + //储存记录,用于返回上一步操作
  65 + this.insertHistory.push(cursorModelPdu);
  66 +
  67 + let tableItemPdu = new pdu['RCRegistryTableItemPdu'];
  68 + tableItemPdu.itemIdx = itemIdx; //直接用时间戳作为id
  69 + tableItemPdu.registerObjId = ApeConsts.CURSOR_OBJ_TABLE_ID;
  70 + tableItemPdu.owner = 0; //收到flash的是这个值,不清楚先写固定
  71 + tableItemPdu.itemData = cursorModelPdu.toArrayBuffer();
  72 +
  73 + //insert
  74 + let tableInsertItemPdu = new pdu['RCRegistryTableInsertItemPdu'];
  75 + tableInsertItemPdu.type = pdu.RCPDU_REG_TABLE_INSERT_PDU; //
  76 + tableInsertItemPdu.items.push(tableItemPdu);
  77 +
  78 + let updateObjPdu = new pdu['RCRegistryUpdateObjPdu'];
  79 + updateObjPdu.objId = ApeConsts.CURSOR_OBJ_TABLE_ID;
  80 + updateObjPdu.subType = tableInsertItemPdu.type;
  81 + updateObjPdu.userData = tableInsertItemPdu.toArrayBuffer();
  82 +
  83 + //同步
  84 + let adapterItemPdu = new pdu['RCAdapterItemPdu'];
  85 + adapterItemPdu.type = pdu.RCPDU_REG_UPDATE_OBJ;
  86 + adapterItemPdu.itemData = updateObjPdu.toArrayBuffer();
  87 +
  88 + let adapterPdu = new pdu['RCAdapterPdu'];
  89 + adapterPdu.type = pdu.RCPDU_REG_ADAPTER;
  90 + adapterPdu.item.push(adapterItemPdu);
  91 +
  92 + loger.log("添加标注->itemIdx=" + tableItemPdu.itemIdx);
  93 + this.sendUniform(adapterPdu, true);
  94 + }
  95 +
  96 + /////鼠标数据接受/////////////////////////////////////////////////////////////////////////////////
  97 + tableInsertHandler(owner, itemIdx, itemData) {
  98 + let cursorModel = this.unPackPdu(owner, itemIdx, itemData);
  99 + loger.log('tableInsertHandler', "activeDocId->", GlobalConfig.activeDocId, "parentId->", cursorModel.parentId);
  100 + loger.log(cursorModel);
  101 + if (cursorModel) {
  102 + this._emit(MessageTypes.CURSOR_UPDATE, cursorModel);
  103 + }
  104 + }
  105 +
  106 + ///////鼠标数据发送/////////////////////////////////////////
  107 + packPdu(_param, _itemIdx) {
  108 + //验证坐标点集合数组是否合法
  109 + if (_param.pointGroup == null || _param.pointGroup.length < 1) {
  110 + this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_APE_INTERFACE_PARAM_WRONG);
  111 + return null;
  112 + }
  113 +
  114 + //判断type类型,根据type设置不同的参数
  115 + let cursorModelPdu = new pdu['RCCursorDataModelPdu'];
  116 +
  117 + //下面4个是必须的参数
  118 + cursorModelPdu.type = DEFAULT_TYPE;
  119 + cursorModelPdu.itemIdx = _itemIdx;
  120 + cursorModelPdu.initiator = GlobalConfig.nodeId;
  121 +
  122 + cursorModelPdu.parentId = GlobalConfig.activeDocId; //当前激活的文档id
  123 + cursorModelPdu.curPageNo = GlobalConfig.activeDocCurPage; //当前激活的文档页码
  124 +
  125 + cursorModelPdu.pointGroup = EngineUtils.arrayToJsonString(_param.pointGroup);
  126 + cursorModelPdu.color = _param.color || "#000000";
  127 + cursorModelPdu.thickness = _param.thickness || 1;
  128 + cursorModelPdu.duration = _param.duration || 0;
  129 +
  130 + return cursorModelPdu;
  131 + }
  132 +
  133 + unPackPdu(owner, itemIdx, itemData) {
  134 + try {
  135 + loger.log("鼠标标注数据->unPackPdu");
  136 + let cursorModelPdu = pdu['RCCursorDataModelPdu'].decode(itemData);
  137 + let _pointGroup = EngineUtils.arrayFromJsonString(cursorModelPdu.pointGroup);
  138 + cursorModelPdu.pointGroup = _pointGroup;
  139 + return cursorModelPdu;
  140 + } catch (err) {
  141 + loger.log("鼠标标注数据->unPackPdu->Pdu解析错误,itemIdx=" + itemIdx + " err:" + err.message);
  142 + }
  143 + return null;
  144 + }
  145 +}
  146 +
  147 +export default CursorApe;
  148 +
@@ -962,6 +962,24 @@ message RCWhiteBoardDataModelPdu { @@ -962,6 +962,24 @@ message RCWhiteBoardDataModelPdu {
962 optional string text= 12;//文本内容 962 optional string text= 12;//文本内容
963 optional bytes data = 13;//暂时预留的参数 963 optional bytes data = 13;//暂时预留的参数
964 } 964 }
  965 +
  966 +message RCCursorDataModelPdu {
  967 + required uint32 type= 1;//类型
  968 + required uint32 itemIdx= 2;//itemIdx 每一次绘制的唯一标识
  969 + required uint32 initiator=3; //绘制来自谁
  970 + required uint32 parentId=4; //父级的id
  971 + required uint32 cur_page_no= 5;//页码
  972 + optional string pointGroup=6; //坐标点集数组的JSON字符串
  973 + optional string color=7 [default = "#000000"]; //颜色
  974 + optional uint32 thickness= 8 ;//线条粗细
  975 + optional uint32 radius= 9;//园的半径
  976 + optional uint32 fontSize= 10;//字体大小
  977 + optional string fontName= 11;//字体名称
  978 + optional string text= 12;//文本内容
  979 + optional bytes data = 13;//暂时预留的参数
  980 + optional uint32 duration = 14; // 事件长度
  981 +}
  982 +
965 message RCClassSendDataModelPdu { 983 message RCClassSendDataModelPdu {
966 optional uint32 item_idx=1; 984 optional uint32 item_idx=1;
967 optional uint32 from=2; 985 optional uint32 from=2;