-
Notifications
You must be signed in to change notification settings - Fork 16
[김이준] Sprint12 #168
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: 김이준
Are you sure you want to change the base?
[김이준] Sprint12 #168
Conversation
This reverts commit e0752c4.
| import org.springframework.web.socket.config.annotation.WebSocketMessageBrokerConfigurer; | ||
|
|
||
| @Configuration | ||
| @EnableWebSocketMessageBroker // STOMP 사용 활성화 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
STOMP 사용 활성화 처리
| @Controller | ||
| @RequiredArgsConstructor | ||
| public class MessageWebSocketController { | ||
|
|
||
| private final MessageService messageService; | ||
|
|
||
| @MessageMapping("/messages") | ||
| public void sendMessage(MessageCreateRequest message) { | ||
| messageService.create(message, java.util.Collections.emptyList()); | ||
| } | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
웹소켓을 활용한 메세지 송신
| //public class WebSocketRequiredEventListener { | ||
| // | ||
| // private final SimpMessagingTemplate messagingTemplate; | ||
| // | ||
| // // 메세지 커밋 이후 | ||
| // @TransactionalEventListener(phase = TransactionPhase.AFTER_COMMIT) | ||
| // public void handleMessage(MessageCreatedEvent event) { | ||
| // MessageDto messageDto = event.getData(); | ||
| // UUID channelId = messageDto.channelId(); | ||
| // | ||
| // messagingTemplate.convertAndSend("/sub/channels." + channelId + ".messages", messageDto); | ||
| // } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
메세지 수신
| @Repository | ||
| public class SseMessageRepository { | ||
|
|
||
| private final ConcurrentLinkedDeque<UUID> eventIdQueue = new ConcurrentLinkedDeque<>(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
이벤트 순서 보장을 위한 Queue 사용
| public class SseMessageRepository { | ||
|
|
||
| private final ConcurrentLinkedDeque<UUID> eventIdQueue = new ConcurrentLinkedDeque<>(); | ||
| private final Map<UUID, SseMessage> messages = new ConcurrentHashMap<>(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
동시성 보장
| // SseEmitter 객체를 생성 | ||
| public SseEmitter connect(UUID receiverId, UUID lastEventId) { | ||
| SseEmitter emitter = createEmitter(receiverId); | ||
| if (lastEventId != null) { | ||
| senderPool.execute(() -> | ||
| restoreEvents(emitter, receiverId, lastEventId) | ||
| ); | ||
| } | ||
|
|
||
| ping(emitter, receiverId, "connect", lastEventId); | ||
|
|
||
| return emitter; | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
객체 전달
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
docker-compose 설정 완료 (nginx 제외)
| // Time-based cleanup - run every hour | ||
| @Scheduled(fixedRate = 3600000) // 1 hour | ||
| public void cleanupOldMessages() { | ||
| Instant cutoff = Instant.now().minusSeconds(MAX_AGE_HOURS * 3600); | ||
| int removed = 0; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
주기적으로 응답 없는 연결 제외
| @RequiredArgsConstructor | ||
| public class WebSocketConfig implements WebSocketMessageBrokerConfigurer { | ||
|
|
||
| private final JwtAuthenticationChannelInterceptor jwtAuthenticationChannelInterceptor; | ||
|
|
||
| @Override | ||
| public void configureMessageBroker(MessageBrokerRegistry config) { | ||
| // 서버가 클라이언트로 메시지를 보낼 때 사용하는 prefix (subscribe) | ||
| config.enableSimpleBroker("/sub"); | ||
| // 클라이언트가 서버로 메시지를 보낼 때 사용하는 prefix (publish) | ||
| config.setApplicationDestinationPrefixes("/pub"); | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
WebSocketMessageBrokerConfigurer 통해 HTTP 요청 간 JWT 인증 수행
| - "8081:8080" | ||
| deploy: | ||
| mode: replicated | ||
| replicas: 3 # 복제 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
3대의 분산 환경 구축
기본 구현사항
웹소켓 구현하기
SSE 구현하기
GET /api/sse배포 아키텍처 구성하기
심화
웹소켓 인증/인가 처리하기
분산 환경 배포 아키텍처 구성하기
질문 답변