@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]);
public void sendCommentToAllClients(Comment comment) {
if (ns != null) {
ns.broadcast("comment:save", comment);
}
}
@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();
}
}
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]);