-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
채팅방 생성 및 채팅 기능 구현
- Loading branch information
Showing
24 changed files
with
534 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
22 changes: 22 additions & 0 deletions
22
src/main/java/coffeemeet/server/chatting/current/implement/ChattingMessageCommand.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
package coffeemeet.server.chatting.current.implement; | ||
|
||
import coffeemeet.server.chatting.current.domain.ChattingMessage; | ||
import coffeemeet.server.chatting.current.domain.ChattingRoom; | ||
import coffeemeet.server.chatting.current.infrastructure.ChattingMessageRepository; | ||
import coffeemeet.server.user.domain.User; | ||
import lombok.RequiredArgsConstructor; | ||
import org.springframework.stereotype.Component; | ||
import org.springframework.transaction.annotation.Transactional; | ||
|
||
@Component | ||
@Transactional | ||
@RequiredArgsConstructor | ||
public class ChattingMessageCommand { | ||
|
||
private final ChattingMessageRepository chattingMessageRepository; | ||
|
||
public ChattingMessage saveChattingMessage(String content, ChattingRoom chattingRoom, User user) { | ||
return chattingMessageRepository.save(new ChattingMessage(content, chattingRoom, user)); | ||
} | ||
|
||
} |
20 changes: 20 additions & 0 deletions
20
src/main/java/coffeemeet/server/chatting/current/implement/ChattingRoomCommand.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
package coffeemeet.server.chatting.current.implement; | ||
|
||
import coffeemeet.server.chatting.current.domain.ChattingRoom; | ||
import coffeemeet.server.chatting.current.infrastructure.ChattingRoomRepository; | ||
import lombok.RequiredArgsConstructor; | ||
import org.springframework.stereotype.Component; | ||
import org.springframework.transaction.annotation.Transactional; | ||
|
||
@Component | ||
@Transactional | ||
@RequiredArgsConstructor | ||
public class ChattingRoomCommand { | ||
|
||
private final ChattingRoomRepository chattingRoomRepository; | ||
|
||
public ChattingRoom saveChattingRoom() { | ||
return chattingRoomRepository.save(new ChattingRoom()); | ||
} | ||
|
||
} |
29 changes: 29 additions & 0 deletions
29
src/main/java/coffeemeet/server/chatting/current/implement/ChattingRoomQuery.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
package coffeemeet.server.chatting.current.implement; | ||
|
||
import static coffeemeet.server.chatting.exception.ChattingErrorCode.CHATTING_ROOM_NOT_FOUND; | ||
|
||
import coffeemeet.server.chatting.current.domain.ChattingRoom; | ||
import coffeemeet.server.chatting.current.infrastructure.ChattingRoomRepository; | ||
import coffeemeet.server.common.execption.InvalidInputException; | ||
import lombok.RequiredArgsConstructor; | ||
import org.springframework.stereotype.Component; | ||
import org.springframework.transaction.annotation.Transactional; | ||
|
||
@Component | ||
@RequiredArgsConstructor | ||
@Transactional(readOnly = true) | ||
public class ChattingRoomQuery { | ||
|
||
private static final String CHATTING_ROOM_NOT_FOUND_MESSAGE = "(%s)번 채팅방을 찾을 수 없습니다."; | ||
|
||
private final ChattingRoomRepository chattingRoomRepository; | ||
|
||
public ChattingRoom getChattingRoomById(Long roomId) { | ||
return chattingRoomRepository.findById(roomId) | ||
.orElseThrow(() -> new InvalidInputException( | ||
CHATTING_ROOM_NOT_FOUND, | ||
String.format(CHATTING_ROOM_NOT_FOUND_MESSAGE, roomId) | ||
)); | ||
} | ||
|
||
} |
8 changes: 8 additions & 0 deletions
8
...ain/java/coffeemeet/server/chatting/current/infrastructure/ChattingMessageRepository.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
package coffeemeet.server.chatting.current.infrastructure; | ||
|
||
import coffeemeet.server.chatting.current.domain.ChattingMessage; | ||
import org.springframework.data.jpa.repository.JpaRepository; | ||
|
||
public interface ChattingMessageRepository extends JpaRepository<ChattingMessage, Long> { | ||
|
||
} |
8 changes: 8 additions & 0 deletions
8
src/main/java/coffeemeet/server/chatting/current/infrastructure/ChattingRoomRepository.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
package coffeemeet.server.chatting.current.infrastructure; | ||
|
||
import coffeemeet.server.chatting.current.domain.ChattingRoom; | ||
import org.springframework.data.jpa.repository.JpaRepository; | ||
|
||
public interface ChattingRoomRepository extends JpaRepository<ChattingRoom, Long> { | ||
|
||
} |
46 changes: 46 additions & 0 deletions
46
src/main/java/coffeemeet/server/chatting/current/presentation/ChattingMessageController.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
package coffeemeet.server.chatting.current.presentation; | ||
|
||
import coffeemeet.server.chatting.current.presentation.dto.ChatStomp; | ||
import coffeemeet.server.chatting.current.service.ChattingMessageService; | ||
import jakarta.validation.Valid; | ||
import java.util.HashMap; | ||
import java.util.Map; | ||
import lombok.RequiredArgsConstructor; | ||
import org.springframework.context.event.EventListener; | ||
import org.springframework.messaging.handler.annotation.MessageMapping; | ||
import org.springframework.messaging.simp.SimpMessageHeaderAccessor; | ||
import org.springframework.messaging.simp.SimpMessageSendingOperations; | ||
import org.springframework.web.bind.annotation.RestController; | ||
import org.springframework.web.socket.messaging.SessionConnectEvent; | ||
import org.springframework.web.socket.messaging.SessionDisconnectEvent; | ||
|
||
@RestController | ||
@RequiredArgsConstructor | ||
public class ChattingMessageController { | ||
|
||
private final SimpMessageSendingOperations simpMessageSendingOperations; | ||
private final ChattingMessageService chattingMessageService; | ||
private final Map<String, Long> sessions = new HashMap<>(); | ||
|
||
@EventListener(SessionConnectEvent.class) | ||
public void onConnect(SessionConnectEvent event) { | ||
String sessionId = String.valueOf(event.getMessage().getHeaders().get("simpSessionId")); | ||
String userId = String.valueOf(event.getMessage().getHeaders().get("nativeHeaders")) | ||
.split("userId=\\[")[1].split("]")[0]; | ||
sessions.put(sessionId, Long.valueOf(userId)); | ||
} | ||
|
||
@EventListener(SessionDisconnectEvent.class) | ||
public void onDisconnect(SessionDisconnectEvent event) { | ||
sessions.remove(event.getSessionId()); | ||
} | ||
|
||
@MessageMapping("/chatting/messages") | ||
public void message(@Valid ChatStomp.Request request, SimpMessageHeaderAccessor accessor) { | ||
Long userId = sessions.get(accessor.getSessionId()); | ||
chattingMessageService.createChattingMessage(request.roomId(), request.content(), userId); | ||
simpMessageSendingOperations.convertAndSend("/sub/chatting/room/" + request.roomId(), | ||
request.content()); | ||
} | ||
|
||
} |
17 changes: 17 additions & 0 deletions
17
src/main/java/coffeemeet/server/chatting/current/presentation/dto/ChatStomp.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
package coffeemeet.server.chatting.current.presentation.dto; | ||
|
||
import jakarta.validation.constraints.NotBlank; | ||
import jakarta.validation.constraints.NotNull; | ||
|
||
public sealed interface ChatStomp permits ChatStomp.Request { | ||
|
||
record Request( | ||
@NotNull | ||
Long roomId, | ||
@NotBlank | ||
String content | ||
) implements ChatStomp { | ||
|
||
} | ||
|
||
} |
25 changes: 25 additions & 0 deletions
25
src/main/java/coffeemeet/server/chatting/current/service/ChattingMessageService.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
package coffeemeet.server.chatting.current.service; | ||
|
||
import coffeemeet.server.chatting.current.domain.ChattingRoom; | ||
import coffeemeet.server.chatting.current.implement.ChattingMessageCommand; | ||
import coffeemeet.server.chatting.current.implement.ChattingRoomQuery; | ||
import coffeemeet.server.user.domain.User; | ||
import coffeemeet.server.user.implement.UserQuery; | ||
import lombok.RequiredArgsConstructor; | ||
import org.springframework.stereotype.Service; | ||
|
||
@Service | ||
@RequiredArgsConstructor | ||
public class ChattingMessageService { | ||
|
||
private final ChattingMessageCommand chattingMessageCommand; | ||
private final ChattingRoomQuery chattingRoomQuery; | ||
private final UserQuery userQuery; | ||
|
||
public void createChattingMessage(Long roomId, String content, Long userId) { | ||
User user = userQuery.getUserById(userId); | ||
ChattingRoom chattingRoom = chattingRoomQuery.getChattingRoomById(roomId); | ||
chattingMessageCommand.saveChattingMessage(content, chattingRoom, user); | ||
} | ||
|
||
} |
17 changes: 17 additions & 0 deletions
17
src/main/java/coffeemeet/server/chatting/current/service/ChattingRoomService.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
package coffeemeet.server.chatting.current.service; | ||
|
||
import coffeemeet.server.chatting.current.implement.ChattingRoomCommand; | ||
import lombok.RequiredArgsConstructor; | ||
import org.springframework.stereotype.Service; | ||
|
||
@Service | ||
@RequiredArgsConstructor | ||
public class ChattingRoomService { | ||
|
||
private final ChattingRoomCommand chattingRoomCommand; | ||
|
||
public void createChattingRoom() { | ||
chattingRoomCommand.saveChattingRoom(); | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
38 changes: 38 additions & 0 deletions
38
src/main/java/coffeemeet/server/common/config/ChattingConfig.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
package coffeemeet.server.common.config; | ||
|
||
import coffeemeet.server.auth.domain.JwtTokenProvider; | ||
import coffeemeet.server.auth.implement.RefreshTokenQuery; | ||
import coffeemeet.server.common.presentation.interceptor.StompInterceptor; | ||
import lombok.RequiredArgsConstructor; | ||
import org.springframework.context.annotation.Configuration; | ||
import org.springframework.messaging.simp.config.ChannelRegistration; | ||
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 | ||
@RequiredArgsConstructor | ||
public class ChattingConfig implements WebSocketMessageBrokerConfigurer { | ||
|
||
private final JwtTokenProvider jwtTokenProvider; | ||
private final RefreshTokenQuery refreshTokenQuery; | ||
|
||
@Override | ||
public void registerStompEndpoints(StompEndpointRegistry registry) { | ||
registry.addEndpoint("/stomp").setAllowedOriginPatterns("*"); | ||
} | ||
|
||
@Override | ||
public void configureMessageBroker(MessageBrokerRegistry registry) { | ||
registry.enableSimpleBroker("/sub"); | ||
registry.setApplicationDestinationPrefixes("/pub"); | ||
} | ||
|
||
@Override | ||
public void configureClientInboundChannel(ChannelRegistration registration) { | ||
registration.interceptors(new StompInterceptor(jwtTokenProvider, refreshTokenQuery)); | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
54 changes: 54 additions & 0 deletions
54
src/main/java/coffeemeet/server/common/presentation/interceptor/StompInterceptor.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
package coffeemeet.server.common.presentation.interceptor; | ||
|
||
import static coffeemeet.server.auth.exception.AuthErrorCode.AUTHENTICATION_FAILED; | ||
import static coffeemeet.server.common.execption.GlobalErrorCode.STOMP_ACCESSOR_NOT_FOUND; | ||
|
||
import coffeemeet.server.auth.domain.JwtTokenProvider; | ||
import coffeemeet.server.auth.implement.RefreshTokenQuery; | ||
import coffeemeet.server.common.execption.InvalidAuthException; | ||
import lombok.RequiredArgsConstructor; | ||
import org.springframework.messaging.Message; | ||
import org.springframework.messaging.MessageChannel; | ||
import org.springframework.messaging.simp.stomp.StompCommand; | ||
import org.springframework.messaging.simp.stomp.StompHeaderAccessor; | ||
import org.springframework.messaging.support.ChannelInterceptor; | ||
import org.springframework.messaging.support.MessageHeaderAccessor; | ||
|
||
@RequiredArgsConstructor | ||
public class StompInterceptor implements ChannelInterceptor { | ||
|
||
private static final String STOMP_ACCESSOR_NOT_FOUND_MESSAGE = "stomp header accessor를 찾을 수 없습니다."; | ||
private static final String HEADER_AUTHENTICATION_FAILED_MESSAGE = "(%s)는 잘못된 권한 헤더입니다."; | ||
|
||
private final JwtTokenProvider jwtTokenProvider; | ||
private final RefreshTokenQuery refreshTokenQuery; | ||
|
||
@Override | ||
public Message<?> preSend(Message<?> message, MessageChannel channel) { | ||
StompHeaderAccessor headerAccessor = MessageHeaderAccessor.getAccessor(message, | ||
StompHeaderAccessor.class); | ||
if (headerAccessor == null) { | ||
throw new InvalidAuthException( | ||
STOMP_ACCESSOR_NOT_FOUND, | ||
STOMP_ACCESSOR_NOT_FOUND_MESSAGE | ||
); | ||
} | ||
|
||
if (headerAccessor.getCommand() == StompCommand.CONNECT) { | ||
String authHeader = String.valueOf(headerAccessor.getNativeHeader("Authorization")); | ||
if (authHeader != null && authHeader.startsWith("Bearer ", 1)) { | ||
String token = authHeader.substring(7, authHeader.length() - 1); | ||
Long userId = jwtTokenProvider.extractUserId(token); | ||
refreshTokenQuery.getRefreshToken(userId); | ||
headerAccessor.addNativeHeader("userId", String.valueOf(userId)); | ||
} else { | ||
throw new InvalidAuthException( | ||
AUTHENTICATION_FAILED, | ||
String.format(HEADER_AUTHENTICATION_FAILED_MESSAGE, authHeader) | ||
); | ||
} | ||
} | ||
return message; | ||
} | ||
|
||
} |
Oops, something went wrong.