From eaa622851fd5c701868518969ea51ec061b223b0 Mon Sep 17 00:00:00 2001 From: xiangpei <xiangpei@timesnew.cn> Date: 星期三, 26 六月 2024 17:03:48 +0800 Subject: [PATCH] websocket集成、加时、强制收卷 --- src/main/java/com/ycl/jxkg/domain/form/AddTimeForm.java | 26 +++++ src/main/java/com/ycl/jxkg/config/WebSocketConfig.java | 19 +++ src/main/java/com/ycl/jxkg/service/ExamService.java | 18 +++ src/main/java/com/ycl/jxkg/enums/WebsocketCommendEnum.java | 27 +++++ src/main/java/com/ycl/jxkg/server/WebsocketServer.java | 120 ++++++++++++++++++++++++ src/main/java/com/ycl/jxkg/domain/form/ForceSubmitForm.java | 24 ++++ src/main/java/com/ycl/jxkg/service/impl/ExamServiceImpl.java | 25 +++++ src/main/java/com/ycl/jxkg/domain/vo/WebsocketDataVO.java | 18 +++ pom.xml | 7 + src/main/java/com/ycl/jxkg/controller/admin/ExamController.java | 16 +++ 10 files changed, 300 insertions(+), 0 deletions(-) diff --git a/pom.xml b/pom.xml index 6a1ebf1..81ae332 100644 --- a/pom.xml +++ b/pom.xml @@ -42,6 +42,13 @@ <dependencies> + + <!-- websocket --> + <dependency> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-starter-websocket</artifactId> + </dependency> + <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> diff --git a/src/main/java/com/ycl/jxkg/config/WebSocketConfig.java b/src/main/java/com/ycl/jxkg/config/WebSocketConfig.java new file mode 100644 index 0000000..906cc46 --- /dev/null +++ b/src/main/java/com/ycl/jxkg/config/WebSocketConfig.java @@ -0,0 +1,19 @@ +package com.ycl.jxkg.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.socket.server.standard.ServerEndpointExporter; + +/** + * @author锛歺p + * @date锛�2024/6/26 15:49 + */ +@Configuration +public class WebSocketConfig { + + @Bean + public ServerEndpointExporter serverEndpointExporter() { + return new ServerEndpointExporter(); + } + +} diff --git a/src/main/java/com/ycl/jxkg/controller/admin/ExamController.java b/src/main/java/com/ycl/jxkg/controller/admin/ExamController.java index 77c04b8..ac0ea48 100644 --- a/src/main/java/com/ycl/jxkg/controller/admin/ExamController.java +++ b/src/main/java/com/ycl/jxkg/controller/admin/ExamController.java @@ -1,7 +1,9 @@ package com.ycl.jxkg.controller.admin; import com.ycl.jxkg.base.Result; +import com.ycl.jxkg.domain.form.AddTimeForm; import com.ycl.jxkg.domain.form.ExamForm; +import com.ycl.jxkg.domain.form.ForceSubmitForm; import com.ycl.jxkg.domain.query.ExamQuery; import com.ycl.jxkg.group.Add; import com.ycl.jxkg.group.Update; @@ -101,4 +103,18 @@ return examService.monitorList(query); } + @PostMapping("/add/time") + @PreAuthorize("hasAuthority('exam:add:time')") + @ApiOperation(value = "娣诲姞鑰冭瘯鏃堕暱", notes = "娣诲姞鑰冭瘯鏃堕暱") + public Result addTime(@RequestBody @Validated AddTimeForm form) { + return examService.addTime(form); + } + + @PostMapping("/force/submit") + @PreAuthorize("hasAuthority('exam:add:time')") + @ApiOperation(value = "寮哄埗鎻愪氦璇曞嵎", notes = "寮哄埗鎻愪氦璇曞嵎") + public Result forceSubmit(@RequestBody @Validated ForceSubmitForm form) { + return examService.forceSubmit(form); + } + } diff --git a/src/main/java/com/ycl/jxkg/domain/form/AddTimeForm.java b/src/main/java/com/ycl/jxkg/domain/form/AddTimeForm.java new file mode 100644 index 0000000..1e17bf1 --- /dev/null +++ b/src/main/java/com/ycl/jxkg/domain/form/AddTimeForm.java @@ -0,0 +1,26 @@ +package com.ycl.jxkg.domain.form; + +import lombok.Data; + +import javax.validation.constraints.NotNull; + +/** + * @author锛歺p + * @date锛�2024/6/26 16:15 + */ +@Data +public class AddTimeForm { + + /** 鑰冭瘯 */ + @NotNull(message = "璇烽�夋嫨鑰冭瘯") + private Integer examId; + + /** 缁欒皝鍔� */ + @NotNull(message = "璇烽�夋嫨缁欒皝鍔�") + private Integer userId; + + /** 娣诲姞澶氬皯鏃堕棿锛氱 */ + @NotNull(message = "璇峰~鍐欏姞鏃剁鏁�") + private Integer addTimeSecond; + +} diff --git a/src/main/java/com/ycl/jxkg/domain/form/ForceSubmitForm.java b/src/main/java/com/ycl/jxkg/domain/form/ForceSubmitForm.java new file mode 100644 index 0000000..ec360fd --- /dev/null +++ b/src/main/java/com/ycl/jxkg/domain/form/ForceSubmitForm.java @@ -0,0 +1,24 @@ +package com.ycl.jxkg.domain.form; + +import lombok.Data; + +import javax.validation.constraints.NotNull; + +/** + * 寮哄埗鎻愪氦璇曞嵎 + * + * @author锛歺p + * @date锛�2024/6/26 16:15 + */ +@Data +public class ForceSubmitForm { + + /** 鑰冭瘯 */ + @NotNull(message = "璇烽�夋嫨鑰冭瘯") + private Integer examId; + + /** 缁欒皝鍔� */ + @NotNull(message = "璇烽�夋嫨瑕佸己鍒舵彁浜ょ殑瀛﹀憳") + private Integer userId; + +} diff --git a/src/main/java/com/ycl/jxkg/domain/vo/WebsocketDataVO.java b/src/main/java/com/ycl/jxkg/domain/vo/WebsocketDataVO.java new file mode 100644 index 0000000..57373d9 --- /dev/null +++ b/src/main/java/com/ycl/jxkg/domain/vo/WebsocketDataVO.java @@ -0,0 +1,18 @@ +package com.ycl.jxkg.domain.vo; + +import lombok.Data; + +/** + * @author锛歺p + * @date锛�2024/6/26 16:43 + */ +@Data +public class WebsocketDataVO { + + /** 鍛戒护锛屾牴鎹笉鍚岀殑鍛戒护鎵ц涓嶅悓鐨勬搷浣� */ + private String commend; + + /** 鎸囦护瀵瑰簲鐨勬暟鎹� */ + private Object data; + +} diff --git a/src/main/java/com/ycl/jxkg/enums/WebsocketCommendEnum.java b/src/main/java/com/ycl/jxkg/enums/WebsocketCommendEnum.java new file mode 100644 index 0000000..c0e3564 --- /dev/null +++ b/src/main/java/com/ycl/jxkg/enums/WebsocketCommendEnum.java @@ -0,0 +1,27 @@ +package com.ycl.jxkg.enums; + +import lombok.Getter; + +/** + * websocket浜嬩欢 + * + * @author锛歺p + * @date锛�2024/6/26 16:50 + */ +@Getter +public enum WebsocketCommendEnum { + + + DELAYED("delayed", "寤堕暱鑰冭瘯鏃堕棿"), + FORCE_SUBMIT("forceSubmit", "寮哄埗鎻愪氦"), + ; + + private final String commend; + + private final String desc; + + WebsocketCommendEnum(String commend, String desc) { + this.commend = commend; + this.desc = desc; + } +} diff --git a/src/main/java/com/ycl/jxkg/server/WebsocketServer.java b/src/main/java/com/ycl/jxkg/server/WebsocketServer.java new file mode 100644 index 0000000..3e27189 --- /dev/null +++ b/src/main/java/com/ycl/jxkg/server/WebsocketServer.java @@ -0,0 +1,120 @@ +package com.ycl.jxkg.server; + +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +import javax.websocket.OnClose; +import javax.websocket.OnMessage; +import javax.websocket.OnOpen; +import javax.websocket.Session; +import javax.websocket.server.PathParam; +import javax.websocket.server.ServerEndpoint; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.CopyOnWriteArraySet; + +/** + * @author锛歺p + * @date锛�2024/6/26 15:51 + */ +@Component +@Slf4j +@ServerEndpoint("/websocket/{userId}") +public class WebsocketServer { + + /** + * 绾跨▼瀹夊叏鐨勬棤搴忕殑闆嗗悎 + */ + private static final CopyOnWriteArraySet<Session> SESSIONS = new CopyOnWriteArraySet<>(); + + /** + * 瀛樺偍鍦ㄧ嚎杩炴帴鏁� + */ + private static final Map<Integer, Session> SESSION_POOL = new HashMap<>(); + + @OnOpen + public void onOpen(Session session, @PathParam(value = "userId") Integer userId) { + try { + SESSIONS.add(session); + SESSION_POOL.put(userId, session); + log.info("銆怶ebSocket娑堟伅銆戞湁鏂扮殑杩炴帴锛屾�绘暟涓猴細" + SESSIONS.size()); + } catch (Exception e) { + e.printStackTrace(); + } + } + + @OnClose + public void onClose(Session session) { + try { + SESSIONS.remove(session); + log.info("銆怶ebSocket娑堟伅銆戣繛鎺ユ柇寮�锛屾�绘暟涓猴細" + SESSIONS.size()); + } catch (Exception e) { + e.printStackTrace(); + } + } + + @OnMessage + public void onMessage(String message) { + log.info("銆怶ebSocket娑堟伅銆戞敹鍒板鎴风娑堟伅锛�" + message); + } + + /** + * 姝や负骞挎挱娑堟伅 + * + * @param message 娑堟伅 + */ + public void sendAllMessage(String message) { + log.info("銆怶ebSocket娑堟伅銆戝箍鎾秷鎭細" + message); + for (Session session : SESSIONS) { + try { + if (session.isOpen()) { + session.getAsyncRemote().sendText(message); + } + } catch (Exception e) { + e.printStackTrace(); + } + } + } + + /** + * 姝や负鍗曠偣娑堟伅 + * + * @param userId 鐢ㄦ埛缂栧彿 + * @param message 娑堟伅 + */ + public void sendOneMessage(Integer userId, String message) { + Session session = SESSION_POOL.get(userId); + if (session != null && session.isOpen()) { + try { + synchronized (session) { + log.info("銆怶ebSocket娑堟伅銆戝崟鐐规秷鎭細" + message); + session.getAsyncRemote().sendText(message); + } + } catch (Exception e) { + e.printStackTrace(); + } + } + } + + /** + * 姝や负鍗曠偣娑堟伅(澶氫汉) + * + * @param userIds 鐢ㄦ埛缂栧彿鍒楄〃 + * @param message 娑堟伅 + */ + public void sendMoreMessage(List<Integer> userIds, String message) { + for (Integer userId : userIds) { + Session session = SESSION_POOL.get(userId); + if (session != null && session.isOpen()) { + try { + log.info("銆怶ebSocket娑堟伅銆戝崟鐐规秷鎭細" + message); + session.getAsyncRemote().sendText(message); + } catch (Exception e) { + e.printStackTrace(); + } + } + } + } + +} diff --git a/src/main/java/com/ycl/jxkg/service/ExamService.java b/src/main/java/com/ycl/jxkg/service/ExamService.java index 0dcb219..d79fdd1 100644 --- a/src/main/java/com/ycl/jxkg/service/ExamService.java +++ b/src/main/java/com/ycl/jxkg/service/ExamService.java @@ -3,7 +3,9 @@ import com.ycl.jxkg.domain.entity.Exam; import com.baomidou.mybatisplus.extension.service.IService; import com.ycl.jxkg.base.Result; +import com.ycl.jxkg.domain.form.AddTimeForm; import com.ycl.jxkg.domain.form.ExamForm; +import com.ycl.jxkg.domain.form.ForceSubmitForm; import com.ycl.jxkg.domain.query.ExamQuery; import com.ycl.jxkg.domain.vo.ExamSubmitVO; @@ -120,4 +122,20 @@ * @return 鐩戞帶鍒楄〃 */ Result monitorList(ExamQuery query); + + /** + * 娣诲姞鑰冭瘯鏃堕棿 + * + * @param form + * @return + */ + Result addTime(AddTimeForm form); + + /** + * 寮哄埗鎻愪氦璇曞嵎 + * + * @param form + * @return + */ + Result forceSubmit(ForceSubmitForm form); } diff --git a/src/main/java/com/ycl/jxkg/service/impl/ExamServiceImpl.java b/src/main/java/com/ycl/jxkg/service/impl/ExamServiceImpl.java index 33c5843..cb54732 100644 --- a/src/main/java/com/ycl/jxkg/service/impl/ExamServiceImpl.java +++ b/src/main/java/com/ycl/jxkg/service/impl/ExamServiceImpl.java @@ -12,14 +12,18 @@ import com.ycl.jxkg.domain.entity.Question; import com.ycl.jxkg.domain.exam.PaperFixQuestionDTO; import com.ycl.jxkg.domain.exam.PaperQuestionSettingDTO; +import com.ycl.jxkg.domain.form.AddTimeForm; import com.ycl.jxkg.domain.form.ExamForm; +import com.ycl.jxkg.domain.form.ForceSubmitForm; import com.ycl.jxkg.domain.query.ExamQuery; import com.ycl.jxkg.domain.question.QuestionObject; import com.ycl.jxkg.domain.vo.*; import com.ycl.jxkg.enums.ExamPaperTypeEnum; +import com.ycl.jxkg.enums.WebsocketCommendEnum; import com.ycl.jxkg.enums.general.ExamStatusEnum; import com.ycl.jxkg.enums.general.ExamSubmitTempStatusEnum; import com.ycl.jxkg.mapper.*; +import com.ycl.jxkg.server.WebsocketServer; import com.ycl.jxkg.service.ExamPaperService; import com.ycl.jxkg.service.ExamService; import com.ycl.jxkg.utils.PageUtil; @@ -50,6 +54,7 @@ private final ClassesUserMapper classesUserMapper; private final ExamPaperMapper examPaperMapper; private final ExamPaperService examPaperService; + private final WebsocketServer websocketServer; /** * 娣诲姞 @@ -433,4 +438,24 @@ IPage<ExamSubmitTempVO> page = PageUtil.getPage(query, ExamSubmitTempVO.class); return Result.ok().data(examSubmitTempMapper.monitorList(page, query)); } + + @Override + public Result addTime(AddTimeForm form) { + WebsocketDataVO websocket = new WebsocketDataVO(); + websocket.setCommend(WebsocketCommendEnum.DELAYED.getCommend()); + websocket.setData(form); + // 鍙戦�亀ebsocket娑堟伅 + websocketServer.sendOneMessage(form.getUserId(), JSON.toJSONString(form)); + return Result.ok("鎿嶄綔鎴愬姛"); + } + + @Override + public Result forceSubmit(ForceSubmitForm form) { + WebsocketDataVO websocket = new WebsocketDataVO(); + websocket.setCommend(WebsocketCommendEnum.FORCE_SUBMIT.getCommend()); + websocket.setData(form); + // 鍙戦�亀ebsocket娑堟伅 + websocketServer.sendOneMessage(form.getUserId(), JSON.toJSONString(form)); + return Result.ok("鎿嶄綔鎴愬姛"); + } } -- Gitblit v1.8.0