-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #9 from 28th-meetup/feat/chat
[Feat] 채팅 기능 추가
- Loading branch information
Showing
30 changed files
with
887 additions
and
7 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
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -36,5 +36,6 @@ out/ | |
### VS Code ### | ||
.vscode/ | ||
|
||
### JRebel ### | ||
rebel.xml | ||
### JREBEL ### | ||
rebel.xml | ||
|
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
Binary file not shown.
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
58 changes: 58 additions & 0 deletions
58
src/main/java/com/kusitms/jipbap/chat/config/RedisConfig.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,58 @@ | ||
package com.kusitms.jipbap.chat.config; | ||
|
||
import com.fasterxml.jackson.databind.ObjectMapper; | ||
import com.fasterxml.jackson.databind.SerializationFeature; | ||
import com.fasterxml.jackson.datatype.jdk8.Jdk8Module; | ||
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; | ||
import com.kusitms.jipbap.chat.domain.dto.MessageDto; | ||
import org.springframework.context.annotation.Bean; | ||
import org.springframework.context.annotation.Configuration; | ||
import org.springframework.data.redis.connection.RedisConnectionFactory; | ||
import org.springframework.data.redis.core.RedisTemplate; | ||
import org.springframework.data.redis.listener.RedisMessageListenerContainer; | ||
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer; | ||
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer; | ||
import org.springframework.data.redis.serializer.StringRedisSerializer; | ||
|
||
@Configuration | ||
public class RedisConfig { | ||
|
||
@Bean | ||
public ObjectMapper objectMapper() { | ||
ObjectMapper objectMapper = new ObjectMapper(); | ||
objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS); | ||
objectMapper.registerModules(new JavaTimeModule(), new Jdk8Module()); | ||
return objectMapper; | ||
} | ||
|
||
// redis 연결, redis 의 pub/sub 기능을 이용하기 위해 pub/sub 메시지를 처리하는 MessageListener 설정(등록) | ||
@Bean | ||
public RedisMessageListenerContainer redisMessageListener(RedisConnectionFactory connectionFactory) { // 1. | ||
RedisMessageListenerContainer container = new RedisMessageListenerContainer(); | ||
container.setConnectionFactory(connectionFactory); // 2. | ||
|
||
return container; | ||
} | ||
|
||
// Redis 데이터베이스와의 상호작용을 위한 RedisTemplate 을 설정. JSON 형식으로 담기 위해 직렬화 | ||
@Bean | ||
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory connectionFactory) { | ||
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>(); | ||
redisTemplate.setConnectionFactory(connectionFactory); | ||
redisTemplate.setKeySerializer(new StringRedisSerializer()); // Key Serializer | ||
redisTemplate.setValueSerializer(new Jackson2JsonRedisSerializer<>(String.class)); // Value Serializer | ||
|
||
return redisTemplate; | ||
} | ||
|
||
// Redis 에 메시지 내역을 저장하기 위한 RedisTemplate을 설정 | ||
@Bean | ||
public RedisTemplate<String, MessageDto> redisTemplateMessage(RedisConnectionFactory connectionFactory) { | ||
RedisTemplate<String, MessageDto> redisTemplateMessage = new RedisTemplate<>(); | ||
redisTemplateMessage.setConnectionFactory(connectionFactory); | ||
redisTemplateMessage.setKeySerializer(new StringRedisSerializer()); // Key Serializer | ||
redisTemplateMessage.setValueSerializer(new GenericJackson2JsonRedisSerializer(objectMapper())); // Value Serializer | ||
|
||
return redisTemplateMessage; | ||
} | ||
} |
26 changes: 26 additions & 0 deletions
26
src/main/java/com/kusitms/jipbap/chat/config/WebSockConfig.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,26 @@ | ||
package com.kusitms.jipbap.chat.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 WebSockConfig implements WebSocketMessageBrokerConfigurer { | ||
|
||
@Override | ||
public void configureMessageBroker(MessageBrokerRegistry config) { | ||
config.enableSimpleBroker("/sub"); //message broker가 subscriber들에게 메세지를 전달할 url (구독 요청) | ||
config.setApplicationDestinationPrefixes("/pub"); //클라이언트가 서버로 메세지를 보낼 url 접두사 지정 (발행 요청) | ||
} | ||
|
||
@Override | ||
public void registerStompEndpoints(StompEndpointRegistry registry) { | ||
registry.addEndpoint("/ws-stomp") //websocket 연결 endpoint | ||
.setAllowedOriginPatterns("*"); | ||
// .withSockJS(); //제거해야 endpoint 연결 성공 | ||
} | ||
} |
40 changes: 40 additions & 0 deletions
40
src/main/java/com/kusitms/jipbap/chat/controller/MessageController.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,40 @@ | ||
package com.kusitms.jipbap.chat.controller; | ||
|
||
|
||
import com.kusitms.jipbap.chat.domain.dto.MessageDto; | ||
import com.kusitms.jipbap.chat.service.RoomService; | ||
import com.kusitms.jipbap.chat.service.MessageService; | ||
import com.kusitms.jipbap.chat.service.RedisPublisher; | ||
import com.kusitms.jipbap.common.response.CommonResponse; | ||
import lombok.RequiredArgsConstructor; | ||
import org.springframework.messaging.handler.annotation.MessageMapping; | ||
import org.springframework.web.bind.annotation.*; | ||
|
||
import java.util.List; | ||
|
||
@RestController | ||
@RequiredArgsConstructor | ||
public class MessageController { | ||
private final RedisPublisher redisPublisher; | ||
private final RoomService roomService; | ||
private final MessageService messageService; | ||
|
||
// 대화 & 대화 저장 | ||
@MessageMapping("/message") | ||
public void message(MessageDto messageDto) { | ||
// 클라이언트의 채팅방(topic) 입장, 대화를 위해 리스너와 연동 | ||
roomService.enterMessageRoom(messageDto.getRoomId()); | ||
|
||
// Websocket 에 발행된 메시지를 redis 로 발행. 해당 채팅방을 구독한 클라이언트에게 메시지가 실시간 전송됨 (1:N, 1:1 에서 사용 가능) | ||
redisPublisher.publish(roomService.getTopic(messageDto.getRoomId()), messageDto); | ||
|
||
// DB & Redis 에 대화 저장 | ||
messageService.saveMessage(messageDto); | ||
} | ||
|
||
// 대화 내역 조회 | ||
@GetMapping("/chat/room/{roomId}/message") | ||
public CommonResponse<List<MessageDto>> loadMessage(@PathVariable String roomId) { | ||
return new CommonResponse<>(messageService.loadMessage(roomId)); | ||
} | ||
} |
45 changes: 45 additions & 0 deletions
45
src/main/java/com/kusitms/jipbap/chat/controller/RoomController.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,45 @@ | ||
package com.kusitms.jipbap.chat.controller; | ||
|
||
import com.kusitms.jipbap.chat.domain.dto.MessageRequestDto; | ||
import com.kusitms.jipbap.chat.domain.dto.MessageResponseDto; | ||
import com.kusitms.jipbap.chat.domain.dto.RoomDto; | ||
import com.kusitms.jipbap.chat.service.RoomService; | ||
import com.kusitms.jipbap.common.response.CommonResponse; | ||
import com.kusitms.jipbap.security.Auth; | ||
import com.kusitms.jipbap.security.AuthInfo; | ||
import lombok.RequiredArgsConstructor; | ||
import org.springframework.web.bind.annotation.*; | ||
|
||
import java.util.List; | ||
|
||
@RestController | ||
@RequestMapping("/chat") | ||
@RequiredArgsConstructor | ||
public class RoomController { | ||
private final RoomService roomService; | ||
|
||
// 채팅방 생성 | ||
@PostMapping("/room") | ||
public CommonResponse<MessageResponseDto> createRoom(@RequestBody MessageRequestDto messageRequestDto, @Auth AuthInfo authInfo) { | ||
return new CommonResponse<>(roomService.createRoom(messageRequestDto, authInfo.getEmail())); | ||
} | ||
|
||
// 사용자 관련 채팅방 전체 조회 | ||
@GetMapping("/rooms") | ||
public CommonResponse<List<MessageResponseDto>> findAllRoomByUser(@Auth AuthInfo authInfo) { | ||
return new CommonResponse<>(roomService.findAllRoomByUser(authInfo.getEmail())); | ||
} | ||
|
||
// 사용자 관련 채팅방 선택 조회 | ||
@GetMapping("/room/{roomId}") | ||
public CommonResponse<RoomDto> findRoom(@PathVariable String roomId, @Auth AuthInfo authInfo) { | ||
return new CommonResponse<>(roomService.findRoom(roomId, authInfo.getEmail())); | ||
} | ||
|
||
// 채팅방 삭제 | ||
@DeleteMapping("/room/{id}") | ||
public CommonResponse<String> deleteRoom(@PathVariable Long id, @Auth AuthInfo authInfo) { | ||
roomService.deleteRoom(id, authInfo.getEmail()); | ||
return new CommonResponse<>("채팅방 삭제 완료"); | ||
} | ||
} |
26 changes: 26 additions & 0 deletions
26
src/main/java/com/kusitms/jipbap/chat/domain/dto/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,26 @@ | ||
package com.kusitms.jipbap.chat.domain.dto; | ||
|
||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties; | ||
import com.fasterxml.jackson.databind.annotation.JsonDeserialize; | ||
import com.kusitms.jipbap.chat.domain.entity.Message; | ||
import lombok.Getter; | ||
import lombok.NoArgsConstructor; | ||
import lombok.Setter; | ||
|
||
@Getter | ||
@Setter | ||
@NoArgsConstructor | ||
@JsonIgnoreProperties(ignoreUnknown = true) | ||
public class MessageDto { | ||
private String senderName; | ||
private String roomId; | ||
private String message; | ||
private String sentTime; | ||
|
||
// 대화 조회 | ||
public MessageDto(Message message) { | ||
this.senderName = message.getSenderName(); | ||
this.roomId = message.getRoom().getRoomId(); | ||
this.message = message.getMessage(); | ||
} | ||
} |
14 changes: 14 additions & 0 deletions
14
src/main/java/com/kusitms/jipbap/chat/domain/dto/MessageRequestDto.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,14 @@ | ||
package com.kusitms.jipbap.chat.domain.dto; | ||
|
||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties; | ||
import lombok.Getter; | ||
import lombok.NoArgsConstructor; | ||
|
||
@Getter | ||
@NoArgsConstructor | ||
@JsonIgnoreProperties(ignoreUnknown =true) | ||
public class MessageRequestDto { | ||
private Long receiverId; // 메세지 수신자 | ||
private String receiverName; // 수신자 이름 (채팅방명으로 쓰임) | ||
private Long storeId; // 1:1 채팅하기를 시작한 가게 정보 | ||
} |
51 changes: 51 additions & 0 deletions
51
src/main/java/com/kusitms/jipbap/chat/domain/dto/MessageResponseDto.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,51 @@ | ||
package com.kusitms.jipbap.chat.domain.dto; | ||
|
||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties; | ||
import com.fasterxml.jackson.annotation.JsonInclude; | ||
import com.kusitms.jipbap.chat.domain.entity.Room; | ||
import lombok.Getter; | ||
import lombok.NoArgsConstructor; | ||
|
||
@Getter | ||
@NoArgsConstructor | ||
@JsonInclude(JsonInclude.Include.NON_NULL) | ||
@JsonIgnoreProperties(ignoreUnknown =true) | ||
public class MessageResponseDto { | ||
private Long id; | ||
private String roomName; | ||
private String sender; | ||
private String roomId; | ||
private String receiver; | ||
private String message; | ||
private String createdAt; | ||
|
||
// 채팅방 생성 | ||
public MessageResponseDto(Room room) { | ||
this.id = room.getId(); | ||
this.roomName = room.getRoomName(); | ||
this.sender = room.getSenderName(); | ||
this.roomId = room.getRoomId(); | ||
this.receiver = room.getReceiverName(); | ||
} | ||
|
||
// 사용자 관련 채팅방 전체 조회 | ||
public MessageResponseDto(Long id, String roomName, String roomId, String sender, String receiver) { | ||
this.id = id; | ||
this.roomName = roomName; | ||
this.sender = sender; | ||
this.roomId = roomId; | ||
this.receiver = receiver; | ||
} | ||
|
||
public MessageResponseDto(String roomId) { | ||
this.roomId = roomId; | ||
} | ||
|
||
public void setLatestMessageContent(String message) { | ||
this.message = message; | ||
} | ||
|
||
public void setLatestMessageCreatedAt(String createdAt) { | ||
this.createdAt = createdAt; | ||
} | ||
} |
42 changes: 42 additions & 0 deletions
42
src/main/java/com/kusitms/jipbap/chat/domain/dto/RoomDto.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,42 @@ | ||
package com.kusitms.jipbap.chat.domain.dto; | ||
|
||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties; | ||
import com.fasterxml.jackson.annotation.JsonInclude; | ||
import com.kusitms.jipbap.user.User; | ||
import lombok.AllArgsConstructor; | ||
import lombok.Getter; | ||
import lombok.Setter; | ||
|
||
import java.io.Serializable; | ||
import java.util.UUID; | ||
|
||
@Getter | ||
@Setter | ||
@AllArgsConstructor | ||
@JsonInclude(JsonInclude.Include.NON_NULL) | ||
@JsonIgnoreProperties(ignoreUnknown =true) | ||
public class RoomDto implements Serializable { | ||
|
||
private static final long serialVersionUID = 298188411555580374L; // Redis 에 저장되는 객체들이 직렬화가 가능하도록 | ||
|
||
private Long id; | ||
private String roomName; // 채팅방 제목 | ||
private String roomId; | ||
private String senderName; // 메시지 송신자 이름 | ||
private String receiverName; // 메시지 수신자 이름 | ||
|
||
// 채팅방 생성 | ||
private RoomDto() { | ||
|
||
} | ||
public static RoomDto create(MessageRequestDto messageRequestDto, User user) { | ||
RoomDto roomDto = new RoomDto(); | ||
roomDto.roomName = messageRequestDto.getReceiverName(); | ||
roomDto.roomId = UUID.randomUUID().toString(); | ||
roomDto.senderName = user.getUsername(); | ||
roomDto.receiverName = messageRequestDto.getReceiverName(); | ||
|
||
return roomDto; | ||
} | ||
|
||
} |
37 changes: 37 additions & 0 deletions
37
src/main/java/com/kusitms/jipbap/chat/domain/entity/Message.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,37 @@ | ||
package com.kusitms.jipbap.chat.domain.entity; | ||
|
||
import com.fasterxml.jackson.annotation.JsonInclude; | ||
import com.kusitms.jipbap.common.entity.DateEntity; | ||
import jakarta.persistence.*; | ||
import lombok.*; | ||
|
||
@Entity | ||
@Getter | ||
@Table(name = "tb_message") | ||
@NoArgsConstructor | ||
@JsonInclude(JsonInclude.Include.NON_NULL) | ||
public class Message extends DateEntity { | ||
@Id | ||
@GeneratedValue(strategy = GenerationType.IDENTITY) | ||
private Long id; | ||
|
||
private String senderName; | ||
|
||
private String receiverName; | ||
|
||
private String message; | ||
|
||
private String sentTime; | ||
|
||
// 1. | ||
@ManyToOne(fetch = FetchType.LAZY) | ||
@JoinColumn(name = "room_id") | ||
private Room room; | ||
|
||
// 대화 저장 | ||
public Message(String senderName, Room room, String message) { | ||
this.senderName = senderName; | ||
this.room = room; | ||
this.message = message; | ||
} | ||
} |
Oops, something went wrong.