Задать вопрос
@Olaff17

Как оганизовать функционал, при добавлении комментария под книгой сообщение о добавлении комментария должно всплывать всем подключённым пользователям?

Если кто-то знает подскажите

@Component
public class SocketEmitter {

    private SocketIoNamespace ns;
    public void socketStart () {

        final ServerWrapper serverWrapper = new ServerWrapper("127.0.0.1", 8081, null); // null means "allow all" as stated in https://github.com/socketio/engine.io-server-java/blob/f8cd8fc96f5ee1a027d9b8d9748523e2f9a14d2a/engine.io-server/src/main/java/io/socket/engineio/server/EngineIoServerOptions.java#L26
        try {
            serverWrapper.startServer();
        } catch (Exception e) {
            e.printStackTrace();
        }
        SocketIoServer server = serverWrapper.getSocketIoServer();
        SocketIoNamespace ns = server.namespace("/");
        ns.on("connection", new Emitter.Listener() {
            @Override
            public void call(Object... args) {
                SocketIoSocket socket = (SocketIoSocket) args[0];
                System.out.println("Client " + socket.getId() + " (" + socket.getInitialHeaders().get("remote_addr") + ") has connected.");
                

            }
        });

    }

}


@RestController
@RequestMapping("/book")
public class AddComment {

    @Autowired
    BookRepository bookRepository;

    @Autowired
    UserRepository userRepository;

    @Autowired
    CommentRepository commentRepository;

    @Autowired
    SocketEmitter socketEmitter;

    @PostMapping("/add-comment")
    public ResponseEntity<Comment> addComment(@RequestBody BookResponse reqBody, Authentication authentication) {
        try {

            User user = userRepository.findById(((UserDetailsImpl) authentication.getPrincipal()).getUser().getUserId())
                    .orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, "User with this ID not found"));

            Book book = bookRepository.findById(reqBody.getBookId())
                    .orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, "Book with this ID not found"));


            Comment comment = new Comment();
            comment.setBook(book);
            comment.setUser(user);
            comment.setText(reqBody.getText());
            comment.setDate(new Date());

            commentRepository.save(comment);


            return ResponseEntity.status(HttpStatus.OK).body(comment);
        } catch (Exception ex) {
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
                    .build();
        }
    }
}


Клиентская часть

useEffect(() => {
    socket.on('comment:save', (data: Comment) => {
    // socket.on('/topic/comments', (comment: Comment) => {
      const comment = JSON.parse(data as any)
      console.log('comment', comment)
      // debugger
      props.book.comments.push(comment);
      // const book = { ...props.book };
      // props.setBookInState(book);
      toast.info('Got event from socket: Book ' + comment.text)
    });
  }, [socket]);
  • Вопрос задан
  • 81 просмотр
Подписаться 1 Простой Комментировать
Решения вопроса 1
Erik_Mironov
@Erik_Mironov
Старые вопросы: *Dies from cringe*
Необходимо добавить метод для отправки сообщения всем подключенным клиентам при добавлении нового комментария.

public void sendCommentToAllClients(Comment comment) {
    if (ns != null) {
        ns.broadcast("comment:save", comment);
    }
}


После сохранения комментария, необходимо отправить его через SocketEmitter всем клиентам.

@PostMapping("/add-comment")
public ResponseEntity<Comment> addComment(@RequestBody BookResponse reqBody, Authentication authentication) {
    try {
        // (...)
        commentRepository.save(comment);

        // Отправляем комментарий всем подключенным клиентам
        socketEmitter.sendCommentToAllClients(comment);

        return ResponseEntity.status(HttpStatus.OK).body(comment);
    } catch (Exception ex) {
        return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
                .build();
    }
}


Вы уже реализовали прослушивание события comment:save на клиенте, поэтому необходимо только убедиться, что данные обрабатываются корректно.

useEffect(() => {
    socket.on('comment:save', (data: Comment) => {
        const comment = JSON.parse(data as any)
        console.log('comment', comment);
        props.book.comments.push(comment);
        // Если setBookInState обновляет состояние, это может быть полезно для перерисовки
        // props.setBookInState({...props.book}); 
        toast.info('Got event from socket: Book ' + comment.text)
    });
}, [socket]);
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы