我正在使用带有 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
我希望得到一些帮助。
我发现使用:
@Autowired
private NewGradeHandler newGradeHandler;
我正在创建一个没有以前连接的新实例。所以,如果这种情况发生在你身上。在您想要使用 WebSocket 的方法中执行以下操作:
声明:
@Autowired
private ApplicationContext applicationContext; // Inyecta el ApplicationContext
使用此实例,请确保 getBean 方法中的 String 与您的类具有相同的名称:
NewGradeHandler newGradeHandler = applicationContext.getBean("NewGradeHandler",NewGradeHandler.class);