WebSocket 未从其类外部触发

问题描述 投票:0回答:1

我正在使用带有 Angular+Ionic 前端的 Spring 后端。我创建了一个 WebSocket,当老师修改 Moodle 中的成绩时触发我的前端。这无关紧要,只是为了给您一些背景信息。

所以问题是 mi fronted 被正确订阅了:

constructor(private apiUserService: ApiUserService) { 
this.webSocket = new WebSocket('ws://localhost:8080/newGrade');
this.webSocket.onmessage = (event) => {
  console.log(event.data)
}}

它正确地获取了第一条消息。问题是,当我更新数据库并调用要触发的处理程序时,它没有响应。我知道 Moodle 中的方法和插件正在工作,因为数据库已更新:

@Autowired
private NewGradeHandler newGradeHandler; 

private final ObjectMapper objectMapper = new ObjectMapper();

@PostMapping("/updateGrade")
public ResponseEntity<String> miEndpoint(@RequestBody Map<String, Object> datos) throws Exception {
    try {
        // Obtener los datos de la solicitud
        Long userId = Long.parseLong(datos.get("userid").toString());
        if (userId != -1) {
            Long courseId = Long.parseLong(datos.get("courseid").toString());
            int mark = Integer.parseInt(datos.get("grade").toString());
            String assignmentName = datos.get("assignmentname").toString();

            // Buscar el usuario y la asignatura
            User student = userService.findById(userId);
            Subject subject = subjectService.getSubject(courseId);

            // Crear una nueva nota o actualizarla si existe
            if (!subjectMarkService.existsByStudentIdAndSubjectIdAndNameMark(student, subject, assignmentName)) {
                Subject_Mark newMark = new Subject_Mark(student, subject, mark, "Ordinaria", assignmentName); 
                subjectMarkService.save(newMark);
                Subject_Mark updatedGrade = subjectMarkService.getLastSubjectMarkAdded();
                sendMessageToWebSocket(updatedGrade);
            } else {
                updateExistingMark(student, subject, mark, assignmentName);
            }

            return ResponseEntity.ok("Nota creada/actualizada correctamente");
        }
        return ResponseEntity.ok("ok");
    } catch (NumberFormatException e) {
        return ResponseEntity.badRequest().body("Error al convertir los datos");
    } catch (RuntimeException e) {
        return ResponseEntity.badRequest().body(e.getMessage());
    }
}

private void updateExistingMark(User student, Subject subject, int mark, String assignmentName) throws Exception {
    Subject_Mark existingMark = subjectMarkService.findByStudentIdAndSubjectIdAndNameMark(student, subject, assignmentName).get();
    existingMark.setMark(mark);
    subjectMarkService.save(existingMark);
}

private void sendMessageToWebSocket(Subject_Mark grade) throws Exception {
TextMessage message = new TextMessage(objectMapper.writeValueAsString(grade));
for (WebSocketSession session : newGradeHandler.getSessions()) {
    session.sendMessage(message);
}

}

我的处理程序及其配置是:

@Configuration@EnableWebSocketpublic class WebSocketConfig implements WebSocketConfigurer {
@Override
public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
    registry.addHandler(new NewGradeHandler(), "/newGrade").setAllowedOrigins("*");
}

@Bean
public WebSocketHandler NewGradeHandler() {
    return new NewGradeHandler(); 
}}

这是我的处理程序:

@Componentpublic class NewGradeHandler extends TextWebSocketHandler {
private final ObjectMapper objectMapper = new ObjectMapper();
private final List<WebSocketSession> sessions = new CopyOnWriteArrayList<>();
@Autowired
private SubjectMarkService subjectMarkService;

@Override
public void afterConnectionEstablished(WebSocketSession session) throws Exception {

    Subject_Mark newGrade = subjectMarkService.getLastSubjectMarkAdded();
    
        TextMessage message = new TextMessage(objectMapper.writeValueAsString(newGrade));
        session.sendMessage(message);
    sessions.add(session);
}

public List<WebSocketSession> getSessions() {
    return sessions;
}}

我搜索了一些指南,但从类内部更新了 wbesocket,我知道它有效:https://medium.com/@parthiban.rajalingam/introduction-to-web-sockets-using-spring-boot-and -角-b11e7363f051

我希望得到一些帮助。

angular spring websocket
1个回答
0
投票

我发现使用:

@Autowired
private NewGradeHandler newGradeHandler; 

我正在创建一个没有以前连接的新实例。所以,如果这种情况发生在你身上。在您想要使用 WebSocket 的方法中执行以下操作:

  1. 声明:

     @Autowired
     private ApplicationContext applicationContext; // Inyecta el ApplicationContext
    
  2. 使用此实例,请确保 getBean 方法中的 String 与您的类具有相同的名称:

NewGradeHandler newGradeHandler = applicationContext.getBean("NewGradeHandler",NewGradeHandler.class);

© www.soinside.com 2019 - 2024. All rights reserved.