-
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
Feat #9 채팅 도메인 개발
- Loading branch information
Showing
11 changed files
with
302 additions
and
0 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
30 changes: 30 additions & 0 deletions
30
src/main/java/com/leets/X/domain/chat/dto/PublishMessage.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,30 @@ | ||
package com.leets.X.domain.chat.dto; | ||
|
||
import lombok.AllArgsConstructor; | ||
import lombok.Getter; | ||
import lombok.NoArgsConstructor; | ||
|
||
import java.io.Serial; | ||
import java.io.Serializable; | ||
|
||
/* | ||
* PublishMessage | ||
* Redis의 pub/sub 과정 데이터를 주고 받을 때, 사용할 직렬화 클래스 | ||
* 24.09.30 - 역직렬화 에러를 해결하지 못하고 있음 | ||
* */ | ||
|
||
@Getter | ||
@NoArgsConstructor | ||
@AllArgsConstructor | ||
public class PublishMessage implements Serializable { | ||
|
||
@Serial | ||
private static final long serialVersionUID = 2082503192322391880L; | ||
|
||
private Long roomId; | ||
|
||
private Long senderId; | ||
|
||
private String content; | ||
|
||
} |
24 changes: 24 additions & 0 deletions
24
src/main/java/com/leets/X/domain/chat/dto/request/MessageDto.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,24 @@ | ||
package com.leets.X.domain.chat.dto.request; | ||
|
||
|
||
import lombok.AllArgsConstructor; | ||
import lombok.Builder; | ||
import lombok.Getter; | ||
import lombok.NoArgsConstructor; | ||
|
||
import java.io.Serializable; | ||
|
||
@Getter | ||
@Builder | ||
@NoArgsConstructor | ||
@AllArgsConstructor | ||
public class MessageDto implements Serializable { | ||
private static final long serialVersionUID = 2082503192322391880L; | ||
|
||
private Long roomId; | ||
|
||
private Long senderId; | ||
|
||
private String content; | ||
|
||
} |
17 changes: 17 additions & 0 deletions
17
src/main/java/com/leets/X/domain/chat/dto/response/PublishMessageResponse.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 com.leets.X.domain.chat.dto.response; | ||
|
||
import com.fasterxml.jackson.annotation.JsonFormat; | ||
import com.leets.X.domain.chat.dto.PublishMessage; | ||
|
||
import java.time.LocalDateTime; | ||
|
||
public record PublishMessageResponse( | ||
Long roomId, | ||
Long senderId, | ||
String content, | ||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime createAt | ||
) { | ||
public PublishMessageResponse(PublishMessage publishMessage) { | ||
this(publishMessage.getRoomId(), publishMessage.getSenderId(), publishMessage.getContent(), LocalDateTime.now()); | ||
} | ||
} |
35 changes: 35 additions & 0 deletions
35
src/main/java/com/leets/X/domain/chat/entity/ChatMessage.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,35 @@ | ||
package com.leets.X.domain.chat.entity; | ||
|
||
|
||
import com.leets.X.domain.chat.dto.PublishMessage; | ||
import com.leets.X.global.common.domain.BaseTimeEntity; | ||
import jakarta.persistence.Id; | ||
import lombok.Builder; | ||
import lombok.Getter; | ||
import org.springframework.data.mongodb.core.mapping.Document; | ||
|
||
import java.time.LocalDateTime; | ||
|
||
@Document | ||
@Getter | ||
@Builder | ||
public class ChatMessage extends BaseTimeEntity { | ||
|
||
@Id | ||
private Long id; // MongoDb에서 사용하는 ObjectId | ||
|
||
private Long roomId; | ||
|
||
private Long senderId; | ||
|
||
private String content; | ||
|
||
public static ChatMessage of(PublishMessage publishMessage) { | ||
return ChatMessage.builder() | ||
.roomId(publishMessage.getRoomId()) | ||
.senderId(publishMessage.getSenderId()) | ||
.content(publishMessage.getContent()) | ||
.build(); | ||
} | ||
|
||
} |
31 changes: 31 additions & 0 deletions
31
src/main/java/com/leets/X/domain/chat/entity/ChatRoom.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,31 @@ | ||
package com.leets.X.domain.chat.entity; | ||
|
||
|
||
import com.leets.X.domain.user.domain.User; | ||
import com.leets.X.global.common.domain.BaseTimeEntity; | ||
import jakarta.persistence.*; | ||
import lombok.*; | ||
|
||
import java.time.LocalDateTime; | ||
|
||
@Builder | ||
@AllArgsConstructor | ||
@NoArgsConstructor(access = AccessLevel.PROTECTED) // 기본 생성자 접근 레벨 PROTECTED | ||
@Entity | ||
public class ChatRoom extends BaseTimeEntity { | ||
|
||
@Id | ||
@GeneratedValue(strategy = GenerationType.IDENTITY) | ||
@Column(name = "room_id") | ||
private Long id; | ||
|
||
@ManyToOne(fetch = FetchType.LAZY) | ||
@JoinColumn(name = "user1_id") | ||
private User user1; | ||
|
||
@ManyToOne(fetch = FetchType.LAZY) | ||
@JoinColumn(name = "user2_id") | ||
private User user2; | ||
|
||
private String lastMessage; | ||
} |
41 changes: 41 additions & 0 deletions
41
src/main/java/com/leets/X/domain/chat/redis/RedisSubscriber.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,41 @@ | ||
package com.leets.X.domain.chat.redis; | ||
|
||
import com.fasterxml.jackson.core.JsonProcessingException; | ||
import com.fasterxml.jackson.databind.ObjectMapper; | ||
import com.leets.X.domain.chat.dto.PublishMessage; | ||
import lombok.RequiredArgsConstructor; | ||
import lombok.extern.slf4j.Slf4j; | ||
import org.springframework.data.redis.connection.Message; | ||
import org.springframework.data.redis.connection.MessageListener; | ||
import org.springframework.data.redis.core.RedisTemplate; | ||
import org.springframework.messaging.simp.SimpMessageSendingOperations; | ||
import org.springframework.stereotype.Service; | ||
|
||
|
||
@Service | ||
@Slf4j | ||
@RequiredArgsConstructor | ||
public class RedisSubscriber implements MessageListener{ | ||
|
||
private final RedisTemplate<String, Object> redisTemplate; | ||
private final ObjectMapper obejctMapper; | ||
private final SimpMessageSendingOperations messageTemplate; | ||
|
||
@Override | ||
public void onMessage(Message message, byte[] pattern) { | ||
// 역직렬화 문자열 | ||
String tmpMessage = redisTemplate.getStringSerializer().deserialize(message.getBody()); | ||
|
||
log.info("구독자 전송 전 message: {}", tmpMessage); | ||
try { | ||
// 역직렬화한 문자열을 PublishMessage로 변환 | ||
PublishMessage publishMessage = obejctMapper.readValue(tmpMessage, PublishMessage.class); | ||
|
||
messageTemplate.convertAndSend("/sub/chats/" + publishMessage.getRoomId(), publishMessage); | ||
log.info("구독자 전송 후 message: {}", publishMessage.getContent()); | ||
} catch (JsonProcessingException e) { | ||
e.printStackTrace(); | ||
throw new RuntimeException(e); | ||
} | ||
} | ||
} |
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,75 @@ | ||
package com.leets.X.global.config; | ||
|
||
import com.leets.X.domain.chat.dto.PublishMessage; | ||
import com.leets.X.domain.chat.redis.RedisSubscriber; | ||
import lombok.RequiredArgsConstructor; | ||
import org.springframework.beans.factory.annotation.Value; | ||
import org.springframework.context.annotation.Bean; | ||
import org.springframework.context.annotation.Configuration; | ||
import org.springframework.data.redis.connection.RedisConnectionFactory; | ||
import org.springframework.data.redis.connection.RedisStandaloneConfiguration; | ||
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory; | ||
import org.springframework.data.redis.core.RedisTemplate; | ||
import org.springframework.data.redis.listener.ChannelTopic; | ||
import org.springframework.data.redis.listener.adapter.MessageListenerAdapter; | ||
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer; | ||
import org.springframework.data.redis.serializer.StringRedisSerializer; | ||
|
||
@Configuration | ||
@RequiredArgsConstructor | ||
public class RedisConfig { | ||
|
||
@Value("${REDIS_HOST}") | ||
private String redisHost; | ||
|
||
@Value("${REDIS_PORT}") | ||
private int redisPort; | ||
|
||
@Bean | ||
public RedisConnectionFactory redisConnectionFactory(){ | ||
// Redis 연동 설정 Host 주소와 Post를 주입해준 redisStandaloneConfiguration를 | ||
RedisStandaloneConfiguration redisStandaloneConfiguration = | ||
new RedisStandaloneConfiguration("localhost", 6379); | ||
// LettuceConnectionFactory의 생성자로 다시 넣어준다. | ||
return new LettuceConnectionFactory(redisStandaloneConfiguration); | ||
} | ||
|
||
@Bean | ||
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory connectionFactory) { | ||
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>(); | ||
redisTemplate.setConnectionFactory(connectionFactory); | ||
redisTemplate.setKeySerializer(new StringRedisSerializer()); | ||
redisTemplate.setValueSerializer(new Jackson2JsonRedisSerializer<>(String.class)); | ||
return redisTemplate; | ||
} | ||
|
||
@Bean | ||
public RedisTemplate<String, PublishMessage> chatRedisTemplate(RedisConnectionFactory connectionFactory){ | ||
RedisTemplate<String, PublishMessage> chatRedisTemplate = new RedisTemplate<>(); | ||
chatRedisTemplate.setConnectionFactory(connectionFactory); | ||
chatRedisTemplate.setKeySerializer(new StringRedisSerializer()); | ||
// Value 직렬화 과정에서 에러 발생할 수 있으니 try catch로 예외 처리 | ||
chatRedisTemplate.setValueSerializer(new Jackson2JsonRedisSerializer<>(String.class)); | ||
|
||
return chatRedisTemplate; | ||
} | ||
|
||
@Bean | ||
public ChannelTopic topic(){ | ||
return new ChannelTopic("/chatRoom"); | ||
} | ||
|
||
|
||
@Bean | ||
public ChannelTopic channelTopic() { | ||
return new ChannelTopic("chatroom"); | ||
} | ||
// 메세지를 구독자에게 보내는 역할 | ||
@Bean | ||
public MessageListenerAdapter listenerAdapter(RedisSubscriber redisSubscriber) { | ||
return new MessageListenerAdapter(redisSubscriber, "onMessage"); | ||
} | ||
|
||
|
||
} | ||
|
30 changes: 30 additions & 0 deletions
30
src/main/java/com/leets/X/global/config/WebSocketConfig.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,30 @@ | ||
package com.leets.X.global.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) { | ||
// 웹소켓이 handshake를 하기 위해 연결하는 endpoint이다. | ||
registry.addEndpoint("/ws") | ||
.setAllowedOriginPatterns("*") // 나중에 도메인으로 변경 | ||
.withSockJS(); | ||
|
||
} | ||
|
||
@Override | ||
public void configureMessageBroker(MessageBrokerRegistry registry) { | ||
// 서버 -> 클라이언트로 발행하는 메시지에 대한 endpoint 설정 | ||
registry.enableSimpleBroker("/sub"); | ||
|
||
// 클라이언트 -> 서버로 발행하는 메시지에 대한 endpoint 설정 | ||
registry.setApplicationDestinationPrefixes("/pub"); | ||
} | ||
} |
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