
💾 spring boot: 3.3.0
💾 jdk: 17
0. start

사용자 나나랑 모모가 같은 게시물을 보고 있을 때, 나나가 댓글을 적을 경우!
나나가 댓글을 추가했다는 알림이 다른 사용자에게도 가는 기능을 구현해 봤다.
다 구현한 건 아니고, 일단은 지금까지 구현한 것만 정리를 하고!
추후에 내가 원하게 수정해서 다시 기록으로 남겨야겠다.
일단 알림을 받기 위해서는 크롬이나 웨일의 '알림'기능이 허용되어 있어야 한다.
- 크롬: 설정 -> 개인 정보 보호 및 보안 -> 사이트 설정 -> 알림 -> 알림 전송이 허용됨 (여기에 도메인 등 추가)
- 웨일: 설정 -> 개인정보 보호 -> 사이트 설정 -> 알림 -> 알림 전송이 허용됨 (여기에 도메인 등 추가)

이렇게 추가를 해야, 알림을 받을 수 있다.
1. build.gradle
.
.
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-websocket'
}
.
.
- `websocket` 의존성 추가
실시간으로 알림을 받는 것을 구현하기 위해 `websocket` 의존성을 build.gradle 에 추가한다.
- WebSocket
- 클라이언트와 서버 간 실시간 양방향 통신을 가능하게 하는 프로토콜
- 양방향 통신: 클라이언트와 서버 간 양방향 실시간 통신을 제공함
- 이벤트 기반 메시징: 서버는 클라이언트에게 메시지를 즉각적으로 전달할 수 있음. 실시간 업데이트, 실시간 채팅, 실시간 게임 등 다양한 실시간 애플리케이션을 구현할 수 있음
- 클라이언트와 서버 간 실시간 양방향 통신을 가능하게 하는 프로토콜
2. WebSocketConfig.java
package com.crud.home.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.messaging.simp.config.MessageBrokerRegistry;
import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker;
import org.springframework.web.socket.config.annotation.StompEndpointRegistry;
import org.springframework.web.socket.config.annotation.WebSocketMessageBrokerConfigurer;
@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/websocket")
.setAllowedOriginPatterns("http://localhost:9090")
.withSockJS(); // STOMP over WebSocket 엔드포인트를 등록
}
@Override
public void configureMessageBroker(MessageBrokerRegistry config) {
config.enableSimpleBroker("/topic"); // /topic으로 시작하는 주소로 메시지를 클라이언트에게 전달하는 간단한 메모리 기반 브로커를 활성화
config.setApplicationDestinationPrefixes("/app"); // @MessageMapping으로 지정된 메서드가 기본적으로 바인딩되는 /app에 메시지 브로커를 설정
}
}
웹소켓 관련 설정을 정의하는 클래스
- annotation
- @Configuration
- 해당 클래스가 Spring의 구성 클래스임을 나타냄
- @EnableWebSocketMessageBroker
- WebSocket 기능을 활성화하고, 메시지 브로커를 사용하도록 설정함
- @Configuration
- `registerStompEndpoints` method
- registerStompEndpoints
- 클라이언트에서 WebSocket 연결을 활성화하는 메서드
- 클라이언트는 `/websocket` 엔드포인트를 사용하여 서버에 WebSocket 연결을 요청할 수 있음
- setAllowedOriginPatterns("http://localhost:9090")
- 클라이언트의 origin을 설정함
- `http://localhost:9090` 에서 실행되는 클라이언트에서만 WebSocket 연결을 허용하도록 설정함
- withSockJS()
- WebSocket이 지원되지 않는 브라우저에서도 대체 수단으로 연결을 제공함
- registerStompEndpoints
- `configureMessageBroker` method
- configureMessageBroker
- 메시지 브로커 구성
메시지 브로커는 클라이언트 간에 메시지를 라우팅하고 전달하는 역할을 함
- 메시지 브로커 구성
- `enableSimpleBroker("/topic")`
- `/topic`으로 시작하는 주체를 구독하는 클라이언트에게 메시지를 전달하는 간단한 메모리 기반의 메시지 브로커를 활성화
- `setApplicationDestinationPrefixes("/app")`
- 클라이언트에서 수신된 메시지를 처리할 메서드가 바인딩될 기본 prefix를 설정함
- configureMessageBroker
3. CommentController.java
@RequiredArgsConstructor
@RestController
@Controller
@Slf4j
@RequestMapping("/comments")
public class CommentsController {
private final CommentsService commentsService;
private final SimpMessagingTemplate messagingTemplate;
// 댓글 작성
@PostMapping( "/add")
public Comments commentCreate(@RequestParam(name="boardId") Long boardId, CommentReqDto dto
, @AuthenticationPrincipal PrincipalDetails principalDetails) {
Long memberId = principalDetails.getMember().getId();
Comments comments = commentsService.insertComments(boardId, dto, memberId);
log.info("commentReqDto = {} " + dto);
log.info("memberId = {} " + memberId);
// WebSocket
String notificationMessage = comments.getBoard().getId() + "번 게시물에 "
+ principalDetails.getMember().getNickname() + " 작성자가 새로운 댓글을 추가했습니다.";
messagingTemplate.convertAndSend("/topic/comments", notificationMessage);
return comments;
}
}
- `private final SimpMessagingTemplate messagingTemplate;` 추가
- WebSocket 및 STOMP 프로토콜을 사용하여 메시지를 전송하는 데 사용됨
- 기존에 댓글 작성하는 controller에서 `commentCreate`에 WebSocket 부분을 추가함
- 현재 로그인한 상태인 멤버의 닉네임과 메시지를 String에 담음
- `messagingTemplate.convertAndSend()` 메소드를 사용하여 `/topin/comments`라는 topic으로 `notificationMessage`를 클라이언트에게 전송함
- 이 topic을 구독하고 있는 모든 클라이언트에게 `notificationMessage`가 전달됨
4. detail.html
<script th:inline="javascript">
/*<![CDATA[*/
// WebSocket 연결 설정
let socket = new SockJS('/websocket');
let stompClient = Stomp.over(socket);
stompClient.connect({}, function (frame) {
console.log('Connected: ' + frame);
stompClient.subscribe('/topic/comments', function (message) {
let notification = message.body; // 일반 텍스트 메시지 그대로 사용
showNotification(notification);
});
});
// 알림을 표시하는 함수
function showNotification(message) {
// 크롬 웹 알림 표시
if (Notification.permission === "granted") {
let notification = new Notification('새로운 댓글 알림', {
body: message,
requireInteraction: true // X 버튼을 끄기 전까지 유지
});
}
}
/*]]>*/
</script>
- WebSocket 관련된 부분만 추가함
- view는 thymeleaf 사용 중
- `SockJS`로 `/websocket` 엔드포인트에 WebSocket 연결 설정함
- `stomp.over(socket)`을 사용해 Stomp 클라이언트를 WebSocket에 연결함
- `stopmpClient.connetct() {..}`
- 서버와 연결 후 연결에 성공하면 콜백 함수 실행됨
- `stompClient.subscribe() {...}`
- `/topic/comments` 채널 구독함
- 새로운 댓글 알림을 받는 데 사용함
- 새로운 메시지가 도착하면 콜백 함수가 실행되고, `sohwNotification` 함수를 호출함
- function showNotification() {...}
- 브라우저의 알림 표시
- `Notification.permission === "granted"`
- 사용자가 알림을 허용했는지 확인함
- `new Notification()
- 새로운 알림 객체 생성함
- 제목은 '새로운 댓글 알림', 내용은 'message' 변수의 값을 사용함
- `requireInteraction: true`를 설정하여 사용자가 알림을 닫기 전까지 알림을 유지함
5. 결과

구현하고 싶었던 게 이게 맞긴 하다.
다만 자신이 작성한 댓글은 자신에게 알림이 오지 않아야 하는데, 현재는 작성자 본인과 상대방에게도 알림이 가고 있다.
크롬이랑 웨일 2개로 테스트를 하고 있는데, 이렇게 댓글 하나를 작성하면 알림이 2개씩 온다.
이 부분은 조금 수정이 필요할 것 같아서, 수정 후 다시 올리도록 해야겠다.
- 내가 적은 댓글은 알림을 받지 않기
- 목록에서도 댓글 알림을 받을 수 있도록 할 수 있는지? 가능하다면 이 부분도 구현하고 싶다.
추가 수정을 하면 다시 기록으로 남겨야겠다.
참고
OpenAi. (2024) ChatGPT (version 3.5)[Large Language model]. https://chat.openai.com
300x250
'SOMEDAY > KEEP' 카테고리의 다른 글
[혼공얄코] 요청 메소드와 응답코드, 리눅스에 대한 학습 (4주 차) (0) | 2024.07.23 |
---|---|
[혼공얄코] 다양한 IT 용어 학습하기 (3주 차) (0) | 2024.07.16 |
[혼공얄코] 가깝지만 먼 AI에 대해 알아가기 (2주 차) (0) | 2024.07.11 |
[PROJECT] Maven to Gradle ~ing (0) | 2024.07.05 |
[혼공얄코] 혼자 공부하는 얄팍한 코딩 지식 시작! 다시 혼공학습단! (0) | 2024.07.02 |