Bläddra i källkod

发送websocket消息相关代码修改

lideyin 5 år sedan
förälder
incheckning
f2e4d64a29

+ 2 - 2
examcloud-core-oe-student-api-provider/src/main/java/cn/com/qmth/examcloud/core/oe/student/api/controller/ExamControlController.java

@@ -113,7 +113,7 @@ public class ExamControlController extends ControllerSupport {
     public void endExam() {
         User user = getAccessUser();
         Long studentId = user.getUserId();
-        String sequenceLockKey = Constants.END_EXAM_LOCK_PREFIX + studentId;
+        String sequenceLockKey = Constants.EXAM_CONTROL_LOCK_PREFIX + user.getUserId();
         //系统在请求结束后会,自动释放锁,无需手动解锁
         SequenceLockHelper.getLock(sequenceLockKey);
 
@@ -191,7 +191,7 @@ public class ExamControlController extends ControllerSupport {
                 fileUrl = upyunFileUrl + req.getFilePath();
             }
             examControlService.sendFileAnswerToWebSocket(req.getExamRecordDataId(), req.getOrder(),
-                    fileUrl, req.getTransferFileType(), user.getUserId());
+                    fileUrl, req.getTransferFileType(), user.getUserId(),user.getRootOrgId());
         } catch (Exception e) {
             examFileAnswerService.deleteFileAnswer(fileAnswerId);
             throw new StatusException("100009", "消息通知失败", e);

+ 5 - 0
examcloud-core-oe-student-base/pom.xml

@@ -61,6 +61,11 @@
             <artifactId>examcloud-global-api</artifactId>
             <version>${examcloud.version}</version>
         </dependency>
+        <dependency>
+            <groupId>cn.com.qmth.examcloud.rpc</groupId>
+            <artifactId>examcloud-ws-api-client</artifactId>
+            <version>${examcloud.version}</version>
+        </dependency>
 
         <dependency>
             <groupId>org.apache.httpcomponents</groupId>

+ 5 - 3
examcloud-core-oe-student-service/src/main/java/cn/com/qmth/examcloud/core/oe/student/service/ExamControlService.java

@@ -28,7 +28,7 @@ public interface ExamControlService {
      * @param handInExamType   交卷类型
      */
     void handInExam(Long examRecordDataId, HandInExamType handInExamType);
-    
+
     /**
      * 断点续考:检查正在进行中的考试
      *
@@ -45,6 +45,7 @@ public interface ExamControlService {
 
     /**
      * 获取考试结束后的相关信息
+     *
      * @param examRecordDataId
      * @return
      */
@@ -62,7 +63,7 @@ public interface ExamControlService {
      * @throws Exception
      */
     void sendFileAnswerToWebSocket(Long examRecordDataId, Integer order,
-                                   String fileUrl, String transferFileType, Long userId) throws Exception;
+                                   String fileUrl, String transferFileType, Long userId, Long rootOrgId) throws Exception;
 
     /**
      * 通过websocket发送二维码扫描信息
@@ -71,7 +72,8 @@ public interface ExamControlService {
      * @param clientId
      * @throws Exception
      */
-    void sendScanQrCodeToWebSocket(String clientId, Long examRecordDataId, Integer order) throws Exception;
+    void sendScanQrCodeToWebSocket(String clientId, Long examRecordDataId, Integer order,
+                                   Long userId, Long rootOrgId) throws Exception;
 
     UpyunSignatureInfo getUpyunSignature(GetUpyunSignatureReq req);
 }

+ 98 - 76
examcloud-core-oe-student-service/src/main/java/cn/com/qmth/examcloud/core/oe/student/service/impl/ExamControlServiceImpl.java

@@ -1,62 +1,18 @@
 package cn.com.qmth.examcloud.core.oe.student.service.impl;
 
-import java.text.SimpleDateFormat;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Locale;
-import java.util.Map;
-import java.util.Random;
-import java.util.Set;
-import java.util.TimeZone;
-import java.util.concurrent.TimeUnit;
-import java.util.stream.Collectors;
-
-import org.apache.commons.collections.CollectionUtils;
-import org.apache.commons.lang.math.RandomUtils;
-import org.apache.commons.lang3.StringUtils;
-import org.apache.commons.lang3.time.DateUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Service;
-import org.springframework.transaction.annotation.Transactional;
-
-import com.google.common.base.Splitter;
-
 import cn.com.qmth.examcloud.api.commons.enums.ExamSpecialSettingsType;
 import cn.com.qmth.examcloud.api.commons.enums.ExamType;
 import cn.com.qmth.examcloud.api.commons.security.bean.User;
+import cn.com.qmth.examcloud.api.commons.security.bean.UserType;
 import cn.com.qmth.examcloud.commons.exception.StatusException;
-import cn.com.qmth.examcloud.commons.util.ByteUtil;
-import cn.com.qmth.examcloud.commons.util.SHA256;
 import cn.com.qmth.examcloud.commons.util.UUID;
-import cn.com.qmth.examcloud.commons.util.UrlUtil;
-import cn.com.qmth.examcloud.commons.util.Util;
+import cn.com.qmth.examcloud.commons.util.*;
 import cn.com.qmth.examcloud.core.oe.student.base.bean.ExamQuestion;
 import cn.com.qmth.examcloud.core.oe.student.base.bean.ExamRecordQuestions;
 import cn.com.qmth.examcloud.core.oe.student.base.utils.CommonUtil;
 import cn.com.qmth.examcloud.core.oe.student.base.utils.QuestionTypeUtil;
-import cn.com.qmth.examcloud.core.oe.student.bean.CheckExamInProgressInfo;
-import cn.com.qmth.examcloud.core.oe.student.bean.CheckQrCodeInfo;
-import cn.com.qmth.examcloud.core.oe.student.bean.EndExamInfo;
-import cn.com.qmth.examcloud.core.oe.student.bean.ExamRecordPaperStruct;
-import cn.com.qmth.examcloud.core.oe.student.bean.GetUpyunSignatureReq;
-import cn.com.qmth.examcloud.core.oe.student.bean.StartExamInfo;
-import cn.com.qmth.examcloud.core.oe.student.bean.UploadedFileAnswerInfo;
-import cn.com.qmth.examcloud.core.oe.student.bean.UpyunSignatureInfo;
-import cn.com.qmth.examcloud.core.oe.student.service.ExamBossService;
-import cn.com.qmth.examcloud.core.oe.student.service.ExamControlService;
-import cn.com.qmth.examcloud.core.oe.student.service.ExamFaceLivenessVerifyService;
-import cn.com.qmth.examcloud.core.oe.student.service.ExamRecordDataService;
-import cn.com.qmth.examcloud.core.oe.student.service.ExamRecordPaperStructService;
-import cn.com.qmth.examcloud.core.oe.student.service.ExamRecordQuestionsService;
-import cn.com.qmth.examcloud.core.oe.student.service.ExamingSessionService;
-import cn.com.qmth.examcloud.core.oe.student.service.FaceBiopsyService;
+import cn.com.qmth.examcloud.core.oe.student.bean.*;
+import cn.com.qmth.examcloud.core.oe.student.service.*;
 import cn.com.qmth.examcloud.core.oe.task.api.ExamCaptureCloudService;
 import cn.com.qmth.examcloud.core.oe.task.api.request.SaveExamCaptureSyncCompareResultReq;
 import cn.com.qmth.examcloud.core.oe.task.api.request.UpdateExamCaptureQueuePriorityReq;
@@ -72,15 +28,7 @@ import cn.com.qmth.examcloud.reports.commons.bean.OnlineExamStudentReport;
 import cn.com.qmth.examcloud.reports.commons.util.ReportsUtil;
 import cn.com.qmth.examcloud.support.Constants;
 import cn.com.qmth.examcloud.support.cache.CacheHelper;
-import cn.com.qmth.examcloud.support.cache.bean.CourseCacheBean;
-import cn.com.qmth.examcloud.support.cache.bean.ExamOrgSettingsCacheBean;
-import cn.com.qmth.examcloud.support.cache.bean.ExamPropertyCacheBean;
-import cn.com.qmth.examcloud.support.cache.bean.ExamSettingsCacheBean;
-import cn.com.qmth.examcloud.support.cache.bean.ExamStudentSettingsCacheBean;
-import cn.com.qmth.examcloud.support.cache.bean.ExtractConfigCacheBean;
-import cn.com.qmth.examcloud.support.cache.bean.ExtractConfigDetailCacheBean;
-import cn.com.qmth.examcloud.support.cache.bean.ExtractConfigPaperCacheBean;
-import cn.com.qmth.examcloud.support.cache.bean.SysPropertyCacheBean;
+import cn.com.qmth.examcloud.support.cache.bean.*;
 import cn.com.qmth.examcloud.support.enums.ExamProperties;
 import cn.com.qmth.examcloud.support.enums.ExamRecordStatus;
 import cn.com.qmth.examcloud.support.enums.FaceBiopsyScheme;
@@ -95,9 +43,30 @@ import cn.com.qmth.examcloud.web.bootstrap.PropertyHolder;
 import cn.com.qmth.examcloud.web.exception.SequenceLockException;
 import cn.com.qmth.examcloud.web.helpers.SequenceLockHelper;
 import cn.com.qmth.examcloud.web.redis.RedisClient;
+import cn.com.qmth.examcloud.ws.api.WsCloudService;
+import cn.com.qmth.examcloud.ws.api.WsPath;
+import cn.com.qmth.examcloud.ws.api.enums.WebSocketEventType;
+import cn.com.qmth.examcloud.ws.api.request.SendFileAnswerMessageReq;
+import cn.com.qmth.examcloud.ws.api.request.SendScanQrCodeMessageReq;
+import cn.com.qmth.examcloud.ws.api.request.SendTextReq;
+import com.google.common.base.Splitter;
 import main.java.com.upyun.Base64Coder;
 import main.java.com.upyun.UpException;
 import main.java.com.upyun.UpYunUtils;
+import org.apache.commons.collections.CollectionUtils;
+import org.apache.commons.lang.math.RandomUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.lang3.time.DateUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.text.SimpleDateFormat;
+import java.util.*;
+import java.util.concurrent.TimeUnit;
+import java.util.stream.Collectors;
 
 /**
  * @author chenken
@@ -127,10 +96,10 @@ public class ExamControlServiceImpl implements ExamControlService {
 
     @Autowired
     private ExamCloudService examCloudService;
-    
+
     @Autowired
     private ExamBossService examBossService;
-    
+
     @Autowired
     private FaceBiopsyService faceBiopsyService;
 
@@ -140,6 +109,9 @@ public class ExamControlServiceImpl implements ExamControlService {
     @Autowired
     private RedisClient redisClient;
 
+    @Autowired
+    private WsCloudService wsCloudService;
+
     private static final String SEPARATOR = "/";
 
     private static final String UNDERLINE = "_";
@@ -260,16 +232,16 @@ public class ExamControlServiceImpl implements ExamControlService {
         if (log.isDebugEnabled()) {
             log.debug("8 创建考试作答记录耗时:" + (System.currentTimeMillis() - startTime) + " ms");
         }
-        
+
         //保存考试次数控制信息
-        ExamBoss eb=examBossService.getExamBoss(examingSession.getExamId());
-        if(eb==null) {
-            eb=new ExamBoss();
+        ExamBoss eb = examBossService.getExamBoss(examingSession.getExamId());
+        if (eb == null) {
+            eb = new ExamBoss();
             eb.setStartCount(0);
         }
-        eb.setStartCount(eb.getStartCount()+1);
+        eb.setStartCount(eb.getStartCount() + 1);
         examBossService.saveExamBoss(examId, eb);
-        
+
         // 初始化考试会话
         startTime = System.currentTimeMillis();
         initializeExamRecordSession(examingSession, examRecordData, examBean);
@@ -387,6 +359,8 @@ public class ExamControlServiceImpl implements ExamControlService {
 
         ExamingSession examSessionInfo = examingSessionService.getExamingSession(examRecordData.getStudentId());
         String clientId;
+        String userId = key.substring(key.lastIndexOf("_") + 1);
+
         // 未开启环境检测,才进行如下校验
         if (!isTestDev(Long.valueOf(examRecordDataId))) {
             // 非环境检测,clientId即examRecordDataId
@@ -401,7 +375,7 @@ public class ExamControlServiceImpl implements ExamControlService {
             }
         } else {
             // 环境检测时,clientId即用户id
-            clientId = key.substring(key.lastIndexOf("_") + 1);
+            clientId = userId;
         }
 
         // 校验通过
@@ -439,7 +413,8 @@ public class ExamControlServiceImpl implements ExamControlService {
         res.setQuestionMainNumber(eqe.getMainNumber());
         res.setSubNumber(getSubNumber(examRecordQuestions, Integer.valueOf(order)));
         try {
-            this.sendScanQrCodeToWebSocket(clientId, Long.valueOf(examRecordDataId), Integer.valueOf(order));
+            this.sendScanQrCodeToWebSocket(clientId, Long.valueOf(examRecordDataId), Integer.valueOf(order),
+                    Long.valueOf(userId), examRecordData.getRootOrgId());
         } catch (Exception e) {
             throw new StatusException("100011", "消息通知失败", e);
         }
@@ -458,8 +433,36 @@ public class ExamControlServiceImpl implements ExamControlService {
      * @throws Exception
      */
     @Override
-    public void sendFileAnswerToWebSocket(Long examRecordDataId, Integer order, String fileUrl, String transferFileType, Long userId) throws Exception {
-
+    public void sendFileAnswerToWebSocket(Long examRecordDataId, Integer order, String fileUrl, String transferFileType,
+                                          Long userId, Long rootOrgId) throws Exception {
+        Map<String, Object> data = new HashMap<String, Object>();
+        data.put("examRecordDataId", examRecordDataId);
+        data.put("order", order);
+        data.put("fileUrl", fileUrl);
+        data.put("transferFileType", transferFileType);
+
+        SendFileAnswerMessageReq sendMessageReq = new SendFileAnswerMessageReq();
+        Long clientId;
+        // 如果是环境检测,则使用用户id(即学生id)作为clientId
+        if (isTestDev(examRecordDataId)) {
+            clientId = userId;
+        }
+        // 不是环境检测,仍然使用考试记录id作为clientId
+        else {
+            clientId = examRecordDataId;
+        }
+        sendMessageReq.setClientId(clientId);
+        sendMessageReq.setEventType(WebSocketEventType.GET_FILE_ANSWER.toString());
+        sendMessageReq.setIsSuccess(true);
+        sendMessageReq.setData(data);
+
+        SendTextReq sendTextReq = new SendTextReq();
+        sendTextReq.setUserType(UserType.STUDENT);
+        sendTextReq.setUserId(userId);
+        sendTextReq.setRootOrgId(rootOrgId);
+        sendTextReq.setPath(WsPath.FILE_ANSWER);
+        sendTextReq.setContent(JsonUtil.toJson(sendMessageReq));
+        wsCloudService.sendText(sendTextReq);
     }
 
     /**
@@ -471,8 +474,26 @@ public class ExamControlServiceImpl implements ExamControlService {
      * @throws Exception
      */
     @Override
-    public void sendScanQrCodeToWebSocket(String clientId, Long examRecordDataId, Integer order) throws Exception {
-
+    public void sendScanQrCodeToWebSocket(String clientId, Long examRecordDataId, Integer order,
+                                          Long userId, Long rootOrgId) throws Exception {
+        Map<String, Object> data = new HashMap<String, Object>();
+        data.put("examRecordDataId", examRecordDataId);
+        data.put("order", order);
+        data.put("scanStatus", "SCANNED");
+        SendScanQrCodeMessageReq sendScanQrCodeMessageReq = new SendScanQrCodeMessageReq();
+        sendScanQrCodeMessageReq.setExamRecordDataId(examRecordDataId);
+        sendScanQrCodeMessageReq.setEventType(WebSocketEventType.SCAN_QR_CODE.toString());
+        sendScanQrCodeMessageReq.setIsSuccess(true);
+        sendScanQrCodeMessageReq.setClientId(clientId);
+        sendScanQrCodeMessageReq.setData(data);
+
+        SendTextReq sendTextReq = new SendTextReq();
+        sendTextReq.setUserType(UserType.STUDENT);
+        sendTextReq.setUserId(userId);
+        sendTextReq.setRootOrgId(rootOrgId);
+        sendTextReq.setPath(WsPath.FILE_ANSWER);
+        sendTextReq.setContent(JsonUtil.toJson(sendScanQrCodeMessageReq));
+        wsCloudService.sendText(sendTextReq);
     }
 
     @Override
@@ -500,9 +521,9 @@ public class ExamControlServiceImpl implements ExamControlService {
             filePath.append(".").append(req.getFileSuffix());
 
             long expiration = expirationDate.getTime() / 1000;
-            String bucketName=PropertyHolder.getString("$upyun.site.1.bucketName");
-            String userName=PropertyHolder.getString("$upyun.site.1.userName");
-            String password=PropertyHolder.getString("$upyun.site.1.password");
+            String bucketName = PropertyHolder.getString("$upyun.site.1.bucketName");
+            String userName = PropertyHolder.getString("$upyun.site.1.userName");
+            String password = PropertyHolder.getString("$upyun.site.1.password");
 
             String policy = policy(bucketName, expiration, filePath.toString(), signDate, md5);
             String sign = sign("POST", getGMTDate(signDate), bucketName, policy, userName, UpYunUtils.md5(password),
@@ -511,8 +532,8 @@ public class ExamControlServiceImpl implements ExamControlService {
             u.setSignature(sign);
             u.setFilePath(filePath.toString());
 
-            String bucketUrl="https://v0.api.upyun.com";
-            String upyunFileUrl=PropertyHolder.getString("$upyun.site.1.domain");
+            String bucketUrl = "https://v0.api.upyun.com";
+            String upyunFileUrl = PropertyHolder.getString("$upyun.site.1.domain");
             u.setUploadUrl(UrlUtil.joinUrl(bucketUrl, bucketName));
             u.setUpyunFileDomain(upyunFileUrl);
         } catch (UpException e) {
@@ -520,6 +541,7 @@ public class ExamControlServiceImpl implements ExamControlService {
         }
         return u;
     }
+
     /**
      * @param bucketName //不能为空
      * @param expiration //不能为空