Parcourir la source

feat: 增加获取实时评论(websocket)

ChenSiTong il y a 6 ans
Parent
commit
bd3a200538

+ 4 - 0
pom.xml

@@ -57,6 +57,10 @@
             <artifactId>spring-boot-starter-tomcat</artifactId>
             <scope>provided</scope>
         </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-websocket</artifactId>
+        </dependency>
         <dependency>
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-starter-test</artifactId>

+ 16 - 0
src/main/java/nju/seec/helper/config/WebsocketConfig.java

@@ -0,0 +1,16 @@
+package nju.seec.helper.config;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.socket.server.standard.ServerEndpointExporter;
+
+/**
+ * @author cst
+ */
+@Configuration
+public class WebsocketConfig {
+    @Bean
+    public ServerEndpointExporter serverEndpointExporter() {
+        return new ServerEndpointExporter();
+    }
+}

+ 5 - 1
src/main/java/nju/seec/helper/controller/CommentController.java

@@ -2,9 +2,11 @@ package nju.seec.helper.controller;
 
 import nju.seec.helper.aspect.auth.Auth;
 import nju.seec.helper.controller.response.PageResponse;
+import nju.seec.helper.controller.websocket.CommentWebsocket;
 import nju.seec.helper.dto.CommentDTO;
 import nju.seec.helper.dto.LoginUser;
 import nju.seec.helper.service.CommentService;
+import nju.seec.helper.util.JsonUtils;
 import nju.seec.helper.util.enums.UserType;
 import nju.seec.helper.vo.CommentVO;
 import org.springframework.data.domain.Pageable;
@@ -34,7 +36,9 @@ public class CommentController {
     @PostMapping
     public CommentVO createComment(LoginUser user,
                                    @Valid @RequestBody CommentDTO commentDTO) {
-        return commentService.createComment(user, commentDTO);
+        CommentVO commentVO = commentService.createComment(user, commentDTO);
+        CommentWebsocket.sendAllMessage(commentDTO.getSlideId(), JsonUtils.toJson(commentVO));
+        return commentVO;
     }
 
     /**

+ 55 - 0
src/main/java/nju/seec/helper/controller/websocket/CommentWebsocket.java

@@ -0,0 +1,55 @@
+package nju.seec.helper.controller.websocket;
+
+import lombok.EqualsAndHashCode;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.websocket.OnClose;
+import javax.websocket.OnError;
+import javax.websocket.OnOpen;
+import javax.websocket.Session;
+import javax.websocket.server.PathParam;
+import javax.websocket.server.ServerEndpoint;
+import java.util.Collections;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.CopyOnWriteArraySet;
+
+/**
+ * @author cst
+ */
+@ServerEndpoint("/api/websocket/comment/slide/{slideId}")
+@RestController
+@Slf4j
+@EqualsAndHashCode
+public class CommentWebsocket {
+    private static Map<Integer, Set<CommentWebsocket>> COMMENT_WEBSOCKET_MAP = new ConcurrentHashMap<>();
+    private Integer slideId;
+    private Session session;
+
+    @OnOpen
+    public void onOpen(Session session, @PathParam("slideId") Integer slideId) {
+        this.session = session;
+        this.slideId = slideId;
+        if (COMMENT_WEBSOCKET_MAP.get(slideId) == null) {
+            COMMENT_WEBSOCKET_MAP.put(slideId, new CopyOnWriteArraySet<>());
+        }
+        COMMENT_WEBSOCKET_MAP.get(slideId).add(this);
+    }
+
+    @OnClose
+    public void onClose() {
+        COMMENT_WEBSOCKET_MAP.get(slideId).remove(this);
+    }
+
+    @OnError
+    public void onError(Throwable throwable) {
+        log.error(throwable.getLocalizedMessage());
+    }
+
+    public static void sendAllMessage(Integer slideId, String message) {
+        COMMENT_WEBSOCKET_MAP.getOrDefault(slideId, Collections.emptySet())
+                .forEach(commentWebsocket -> commentWebsocket.session.getAsyncRemote().sendText(message));
+    }
+}