팀 프로젝트 2일 차 내가 맡은 구현부는 card에서 사용자들이 댓글로 대화할 수 있는 기능에, 댓글이 생성되면 해당 card의 모든 worker에게 알림을 보내는 기능 구현이다.
댓글을 작성하는 CRUD 기능구현 설명은 블로그 내용에서 생략하고, 알림을 보내는 기능 위주로 설명하겠다.
특정 카드에 댓글이 추가될 때 작업자에게 알림을 보내는 메서드로, CommentService에서 구현한 해당 카드에 대한 가장 최근의 댓글을 가져온 후, 카드에 연결된 worker들을 찾는다. 작업자 목록을 순회하면서 각 작업자에게 SSE (Server-Sent Events) Emitter를 사용하여 알림을 전송한다. 알림을 보낸 후에는 알림 정보를 데이터베이스에 저장하고, 작업자의 알림 수를 증가한다. 만약 예외가 발생한 경우 해당 작업자의 SSE Emitter를 제거한다.
// NotificationService.java
@Transactional
public void notifyComment(Long cardId) {
// 카드에 대한 가장 최근의 댓글을 찾습니다.
Comment receiveComment = commentService.findLatestComment(cardId);
// 해당 카드에 연결된 작업자 목록을 가져옵니다.
List<Long> workers = workerRepository.findByCardId(cardId);
// 작업자 목록을 순회합니다.
for (Long workerId : workers) {
// 작업자에 대한 SSE (Server-Sent Events) Emitter가 있는지 확인합니다.
if (NotificationController.sseEmitters.containsKey(workerId)) {
// 작업자에 대한 SSE Emitter를 가져옵니다.
SseEmitter sseEmitter = NotificationController.sseEmitters.get(workerId);
try {
// 댓글에 대한 이벤트 데이터를 구성합니다.
Map<String, String> eventData = new HashMap<>();
eventData.put("sender", receiveComment.getNickname() + " 님이 댓글을 작성했습니다.");
eventData.put("contents", receiveComment.getComment());
// SSE Emitter를 통해 이벤트를 전송합니다.
sseEmitter.send(SseEmitter.event().name("addComment").data(eventData));
// 알림 객체를 생성하고 저장합니다.
Notification notification = Notification.builder()
.cardId(cardId)
.userId(workerId)
.sender(receiveComment.getNickname())
.contents(receiveComment.getComment())
.build();
notificationRepository.save(notification);
// 작업자의 알림 수를 증가시킵니다.
notificationCounts.put(workerId,
notificationCounts.getOrDefault(workerId, 0) + 1);
// 알림 수를 SSE Emitter를 통해 전송합니다.
sseEmitter.send(SseEmitter.event().name("notificationCount")
.data(notificationCounts.get(workerId)));
} catch (IOException e) {
// 예외가 발생한 경우 해당 작업자의 SSE Emitter를 제거합니다.
NotificationController.sseEmitters.remove(workerId);
}
}
}
}
worker들의 id를 가져오기 위해 Qdsl로 작성했다.
// WorkerRepositoryCustomImpl.java
@Override
public List<Long> findByCardId(Long cardId) {
QWorker worker = QWorker.worker;
return jpaQueryFactory.select(worker.user_id)
.from(worker)
.where(worker.card_id.eq(cardId))
.fetch();
}
notifyComment(Long cardId) 메서드를 CommentController의 createComment 메서드에 적용하여, 댓글 생성시 알림을 보낼 수 있다.
// CommentController.java
@RestController
@RequiredArgsConstructor
@RequestMapping("/cards/{cardId}/comments")
public class CommentController {
private final CommentService commentService;
private final NotificationService notificationService;
@PostMapping
public ResponseEntity<Void> createComment(
@PathVariable Long cardId,
@RequestBody CommentRequestDto commentRequestDto,
@AuthenticationPrincipal UserDetailsImpl userDetails
) {
commentService.createComment(cardId, commentRequestDto, userDetails.getUser());
notificationService.notifyComment(cardId); // 알림 메서드 적용
return ResponseEntity.status(HttpStatus.CREATED).build();
}
...
}'Project' 카테고리의 다른 글
| Project Day 3 : 프로젝트 제목 선정, 역할분담, todo (0) | 2024.03.28 |
|---|---|
| Project Day 2 : S.A 작성 (0) | 2024.03.27 |
| 팀 프로젝트 3. Trello 1일차 (프로젝트 스코프 정하기) (1) | 2024.03.18 |
| 팀 프로젝트 2. OTT 추천 커뮤니티 서버 (뉴스피드) (0) | 2024.02.16 |
| 팀 프로젝트 1. 학생 관리 프로그램 (0) | 2024.01.17 |