123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582 |
- import io from 'socket.io-client';
- const address: any = import.meta.env.VITE_APP_BASE_API;
- const token: any = localStorage.getItem('token');
- const myInfo: any = localStorage.getItem('userInfo');
- let socket: any = {}; //ws实例对象
- let timerManager: any = {}; //计时器管理
- let parameter: any = {}; //参数
- let testTime: number = 0; //默认时长
- let userInfo: any = JSON.parse(myInfo); //用户信息
- let beatTime: number = 10000; //心跳频率
- let loading: any = null; //遮罩层
- let version: string = ''; //ws接口版本v2表示单ws多项目
- let examStateList: any = []; //当前状态码
- let testList: any = []; //区列表
- let wkList: any = []; //工作站列表
- export const initWs = (data: any, callback: any) => {
- examStateList = []; //当前状态码
- testList = []; //区列表
- wkList = []; //工作站列表
- loading = ElLoading.service({ text: '正在初始化,请稍候', background: 'rgba(0, 0, 0, 0.8)', customClass: `sports ${data.parameter.project}` });
- parameter = data.parameter;
- testTime = data.testTime;
- version = data.version || '';
- testList = data.parameter.area.split(',');
- examStateList = testList.map((item: any) => {
- let examId = `${parameter.project}_${item}`;
- let obj = {
- examState: 0,
- examId: examId,
- beatNumber: 0
- };
- return obj;
- });
- socket = io(address + '/midexam', {
- transports: ['websocket', 'polling'],
- query: {
- Authorization: token,
- sysuuid: token
- }
- });
- let loadingTime = setTimeout(() => {
- //30秒还在0状态就算超时
- let list = examStateList.filter((item: any) => {
- return item.examState == 0;
- });
- //考虑到多开只有一个在线也有效的
- if (list.length == testList.length) {
- clearTimeout(loadingTime);
- callback({ cmd: 'disconnect_request', data: { message: 'WS连接超时' } });
- }
- }, 20000);
- socket.on('connect', (e: any) => {
- callback({ cmd: 'mySid', data: { sid: socket.id.replace('/midexam#', '') } });
- if (testList.length > 1) {
- //单WS多区
- testList.forEach((item: any) => {
- let examId = `${parameter.project}_${item}`;
- if (parameter.taskId) {
- getTaskStarts(examId);
- } else {
- getExamStarts(examId);
- }
- getNetWork(examId, (e: any) => {
- if (!e.status) {
- callback({ cmd: 'disconnect_request', exam_id: examId, data: { message: '工作站未响应' } });
- }
- });
- });
- } else {
- //单WS单区
- let examId = parameter.examId;
- if (parameter.taskId) {
- getTaskStarts(examId);
- } else {
- getExamStarts(examId);
- }
- getNetWork(examId, (e: any) => {
- if (!e.status) {
- callback({ cmd: 'disconnect_request', exam_id: examId, data: { message: '工作站未响应' } });
- }
- });
- }
- });
- socket.on('msg2frontend', (e: any) => {
- callback(e);
- //实时状态
- if (e.cmd === 'exam_status') {
- let index = examStateList.findIndex((item: any) => {
- return item.examId == e.exam_id;
- });
- if (index != -1) {
- examStateList[index].examState = e.data;
- examStateList[index].beatNumber = examStateList[index].beatNumber + 1;
- }
- }
- //工作站状态
- if (e.cmd === 'init_result') {
- if (e.status == 666) {
- let data = {
- wk_id: e.data.wk_id,
- examId: e.exam_id
- };
- wkList.push(data);
- }
- }
- //测试违规
- if (e.cmd === 'warning_result') {
- }
- //后端播报语音
- if (e.cmd === 'return_audio_msg') {
- }
- //错误提示
- if (e.cmd === 'info_result') {
- }
- //错误提示
- if (e.cmd === 'error_result') {
- }
- //测试中违规提示
- if (e.cmd === 'warning_notify') {
- }
- //断线状态
- if (e.cmd === 'disconnect_request') {
- if (testList.length == 1) {
- getExit();
- //let examId = e?.exam_id || '';
- //getExit(examId);
- }
- }
- //状态变更
- if (e.cmd === 'set_exam_state') {
- let index = examStateList.findIndex((item: any) => {
- return item.examId == e.exam_id;
- });
- if (index != -1) {
- examStateList[index].examState = e.data;
- }
- if (e.data == 3) {
- //关闭遮罩层
- loading?.close();
- clearTimeout(loadingTime);
- }
- }
- //新建测试后返回信息,获取result_id
- if (e.cmd === 'open_one_test_ack') {
- }
- //人脸识别状态
- if (e.cmd === 'face_check_result') {
- }
- //测试结束结果
- if (e.cmd === 'oneresult') {
- }
- //结果生成完成(视频图片)
- if (e.cmd === 'static_urls_finished') {
- }
- //选择学生或测试结束后返回的数据
- if (e.cmd === 'result_info') {
- }
- });
- socket.on('disconnect', (e: any) => {
- callback(e);
- getExit();
- });
- };
- /**
- * 发送命令
- * @param type发送类型:v2版是单WS多人的项目
- * msgfrom_frontend:测试中命令交互,
- * get_exam_status:心跳,
- * exam_ends:结束测试,
- * fe_reconnect:重连,
- * task_starts:课程开启测试,
- * exam_starts:开启测试,
- * join_exam_room:加入房间,
- * @param data发送数据:
- * msgfrom_frontend发送cmd的参:
- * open_one_test:创建测试将由3转40,
- * start_face_recognition:开始人脸识别将由40转41,
- * stop_face_recognition:停止人脸识别将由41转43,
- * face_confirm_only:人脸确认即将测试,
- * start_one_test:开始测试将由43转42,
- * finish_one_test:正在测试中结束并下一次将由42转6转3,
- * close_one_test:中断任何阶段将由42、43、41、40转3,
- * suspend_face_recognition_channels:工作站识别的短跑,某道识别到了人就停止某道的识别,
- * resume_face_recognition_channels:工作站识别的短跑,重新开启某一道的识别,
- * next_test:,
- * result_info:,
- * @param callback回调函数
- */
- export const sendMessage = (type: string, data: any, callback?: () => void) => {
- if (socket.connected) {
- callback = callback || function () {};
- //版本2就拼接进去
- if (version == 'v2') {
- type = type + '_' + version;
- }
- socket.emit(type, JSON.stringify(data), callback);
- }
- };
- /**
- * 课程连接成功
- */
- const getTaskStarts = (data?: any) => {
- let examId = data ? data : parameter.examId;
- sendMessage(
- 'task_starts',
- {
- data: 'start_' + examId,
- class_id: parameter.classes,
- exam_type: parameter.standard,
- task_cate: parameter.taskCate,
- gesture: parameter.gesture,
- demo: parameter.demo,
- test_time: testTime
- },
- () => {}
- );
- };
- /**
- * 连接成功
- */
- const getExamStarts = (data?: any) => {
- let examId = data ? data : parameter.examId;
- sendMessage(
- 'exam_starts',
- {
- data: 'start_' + examId,
- class_id: parameter.classes,
- exam_type: parameter.standard,
- gesture: parameter.gesture,
- demo: parameter.demo,
- test_time: testTime
- },
- () => {}
- );
- };
- /**
- * 创建测试
- */
- export const openOneTest = (data?: any) => {
- return new Promise((resolve, reject) => {
- let examId = data ? data : parameter.examId;
- let index = examStateList.findIndex((item: any) => {
- return item.examId == examId;
- });
- sendMessage('msgfrom_frontend', {
- data: {
- cmd: 'open_one_test',
- exam_id: examId
- }
- });
- let timer1 = setInterval(() => {
- if (examStateList[index].examState == 40) {
- clearInterval(timer1);
- clearTimeout(timer2);
- resolve({ data: examStateList[index].examState });
- }
- }, 250);
- let timer2 = setTimeout(() => {
- if (examStateList[index].examState == 3) {
- clearInterval(timer1);
- clearTimeout(timer2);
- reject({ cmd: 'disconnect_request', exam_id: examId, data: { message: '超时:open_one_test' } });
- }
- }, 30000);
- });
- };
- /**
- * 开始人脸识别
- */
- export const startFace = (data?: any) => {
- return new Promise((resolve, reject) => {
- let examId = data ? data : parameter.examId;
- let index = examStateList.findIndex((item: any) => {
- return item.examId == examId;
- });
- sendMessage('msgfrom_frontend', {
- data: {
- cmd: 'start_face_recognition',
- exam_id: examId
- }
- });
- let timer1 = setInterval(() => {
- if (examStateList[index].examState == 41) {
- clearInterval(timer1);
- clearTimeout(timer2);
- resolve({ data: examStateList[index].examState });
- }
- }, 250);
- let timer2 = setTimeout(() => {
- if (examStateList[index].examState == 40) {
- clearInterval(timer1);
- clearTimeout(timer2);
- reject({ cmd: 'disconnect_request', exam_id: examId, data: { message: '超时:start_face_recognition' } });
- }
- }, 30000);
- });
- };
- /**
- * 停止人脸识别
- */
- export const stopFace = (data?: any) => {
- return new Promise((resolve, reject) => {
- let examId = data ? data : parameter.examId;
- let index = examStateList.findIndex((item: any) => {
- return item.examId == examId;
- });
- sendMessage('msgfrom_frontend', {
- data: {
- cmd: 'stop_face_recognition',
- exam_id: examId
- }
- });
- let timer1 = setInterval(() => {
- if (examStateList[index].examState == 43) {
- clearInterval(timer1);
- clearTimeout(timer2);
- resolve({ data: examStateList[index].examState });
- }
- }, 250);
- let timer2 = setTimeout(() => {
- if (examStateList[index].examState == 41) {
- clearInterval(timer1);
- clearTimeout(timer2);
- reject({ cmd: 'disconnect_request', exam_id: examId, data: { message: '超时:stop_face_recognition' } });
- }
- }, 30000);
- });
- };
- /**
- * 确认并提交人脸
- */
- export const faceConfirmOnly = (data: any, callback?: any) => {
- let examId = data.exam_id ? data.exam_id : parameter.examId;
- let myData = null;
- if (Array.isArray(data)) {
- //数组类型
- myData = {
- cmd: 'face_confirm_only',
- data
- };
- } else {
- //对象类型
- myData = {
- cmd: 'face_confirm_only',
- exam_id: examId,
- result_id: data.result_id,
- student_id: data.student_id,
- gender: data.gender
- };
- }
- sendMessage(
- 'msgfrom_frontend',
- {
- data: myData
- },
- () => {
- callback();
- }
- );
- };
- /**
- * 开始测试
- */
- export const startOneTest = (data?: any, callback?: any) => {
- let examId = data ? data : parameter.examId;
- sendMessage(
- 'msgfrom_frontend',
- {
- data: {
- cmd: 'start_one_test',
- exam_id: examId
- }
- },
- () => {
- callback();
- }
- );
- };
- /**
- * 停止测试
- */
- export const finishOneTest = (data?: any) => {
- return new Promise((resolve, reject) => {
- let examId = data ? data : parameter.examId;
- let index = examStateList.findIndex((item: any) => {
- return item.examId == examId;
- });
- sendMessage('msgfrom_frontend', {
- data: {
- cmd: 'finish_one_test',
- exam_id: examId
- }
- });
- let timer1 = setInterval(() => {
- if (examStateList[index].examState == 3) {
- clearInterval(timer1);
- clearTimeout(timer2);
- resolve({ data: examStateList[index].examState });
- }
- }, 250);
- let timer2 = setTimeout(() => {
- if (examStateList[index].examState == 42) {
- clearInterval(timer1);
- clearTimeout(timer2);
- reject({ cmd: 'disconnect_request', exam_id: examId, data: { message: '超时:finish_one_test' } });
- }
- }, 60000);
- });
- };
- /**
- * 关闭测试测试
- */
- export const closeOneTest = (data?: any) => {
- return new Promise((resolve, reject) => {
- let examId = data ? data : parameter.examId;
- let index = examStateList.findIndex((item: any) => {
- return item.examId == examId;
- });
- sendMessage('msgfrom_frontend', {
- data: {
- cmd: 'close_one_test',
- exam_id: examId
- }
- });
- let timer1 = setInterval(() => {
- if (examStateList[index].examState == 3) {
- clearInterval(timer1);
- clearTimeout(timer2);
- resolve({ data: examStateList[index].examState });
- }
- }, 250);
- let timer2 = setTimeout(() => {
- if (examStateList[index].examState != 3) {
- clearInterval(timer1);
- clearTimeout(timer2);
- reject({ cmd: 'disconnect_request', exam_id: examId, data: { message: '超时:close_one_test' } });
- }
- }, 30000);
- });
- };
- /**
- * 某道识别到了人就停止某道的识别
- */
- export const suspendFaceRecognitionChannels = (data: any) => {
- let track = data;
- sendMessage('msgfrom_frontend', {
- data: {
- cmd: 'suspend_face_recognition_channels',
- track: track
- }
- });
- };
- /**
- * 某道重新开始识别
- */
- export const resumeFaceRecognitionChannels = (data: any) => {
- let track = data;
- sendMessage('msgfrom_frontend', {
- data: {
- cmd: 'resume_face_recognition_channels',
- track: track
- }
- });
- };
- /**
- * 心跳
- */
- export const getNetWork = (data: any, callback?: any) => {
- timerManager[data] = setInterval(() => {
- let obj = wkList.find((item: any) => {
- return item.examId == data;
- });
- if (obj == undefined) {
- return false;
- }
- let wk_id = obj.wk_id;
- let examId = data ? data : parameter.examId;
- sendMessage(
- 'get_exam_status',
- {
- exam_id: examId,
- wk_id: wk_id,
- school_id: userInfo.school_id || null
- },
- () => {
- //如果心跳停止了就退出去
- let index = examStateList.findIndex((item: any) => {
- return item.examId == examId;
- });
- if (index == -1) {
- return false;
- }
- let beforBeatNumber = JSON.parse(JSON.stringify(examStateList[index].beatNumber));
- setTimeout(() => {
- //5秒后验证是否有变
- if (beforBeatNumber == examStateList[index].beatNumber) {
- //异常
- callback({ status: false });
- } else {
- //正常
- callback({ status: true });
- }
- }, 5000);
- }
- );
- }, beatTime);
- };
- /**
- * 关闭项目
- */
- export const examEnds = () => {
- getExit();
- };
- /**
- * 退出
- */
- const getExit = (data?: any) => {
- //关闭遮罩层
- loading?.close();
- //通知工作站关闭
- if (testList.length > 1 && !data) {
- //单WS多区
- examStateList.forEach((item: any) => {
- let examId = item.examId;
- sendMessage('exam_ends', {
- data: 'end_' + examId,
- class_id: parameter.classes
- });
- });
- //清除计时器
- getClearTimer();
- //如果正在连接就关闭
- if (socket?.connected) {
- socket?.close();
- }
- } else {
- //单WS单区
- let examId = data ? data : parameter.examId;
- sendMessage('exam_ends', {
- data: 'end_' + examId,
- class_id: parameter.classes
- });
- if (!data) {
- //清除计时器
- getClearTimer();
- //如果正在连接就关闭
- if (socket?.connected) {
- socket?.close();
- }
- }
- }
- };
- /**
- * 清空定时任务
- */
- const getClearTimer = () => {
- for (let key in timerManager) {
- if (timerManager.hasOwnProperty(key)) {
- clearInterval(timerManager[key]);
- timerManager[key] = null;
- }
- }
- };
|