Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ dependencies {
implementation 'org.springframework.boot:spring-boot-starter-validation'
implementation 'org.springframework.boot:spring-boot-starter-web'

implementation 'org.springframework.boot:spring-boot-starter-websocket'



/* auth */
implementation 'org.springframework.boot:spring-boot-starter-security'
implementation 'io.jsonwebtoken:jjwt-api:0.11.5'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@ public ResponseEntity<ResultResponse> signup(
) {
SignupResponseDto signupResDto = authService.signup(signupReqDto);

// chatRoomRepository.createChatRoom(signupResDto.getEmail()); //채팅방 생성


return ResponseEntity.ok(ResultResponse.of(ResponseCode.SIGNUP_SUCCESS, signupResDto));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
import com.techeer.fashioncloud.domain.post.dto.response.PostCreateResponseDto;
import com.techeer.fashioncloud.domain.post.dto.response.PostInfoResponseDto;
import com.techeer.fashioncloud.domain.post.service.PostService;
import com.techeer.fashioncloud.domain.story.ChatService;
import com.techeer.fashioncloud.domain.story.model.ChatMessage;
import com.techeer.fashioncloud.domain.user.entity.User;
import com.techeer.fashioncloud.global.dto.CustomPageRequest;
import com.techeer.fashioncloud.global.dto.PaginatedResponse;
Expand All @@ -31,6 +33,7 @@
public class PostController {

private final PostService postService;
private final ChatService chatService;

@PostMapping
@PreAuthorize("hasAnyRole('USER', 'ADMIN')")
Expand All @@ -40,6 +43,18 @@ public ResponseEntity<ResultResponse> create(
@LoginUser User loginUser
) {
PostCreateResponseDto resDto = postService.create(loginUser, reqDto);


ChatMessage message = ChatMessage.builder()
.roomId(loginUser.getEmail()) // 팔로워들의 기본키 id를 사용하도록 설정
.sender(loginUser.getEmail())
.message(resDto)
.build();

// 메시지 전송
chatService.sendMessage(message, loginUser);


return ResponseEntity.ok(ResultResponse.of(ResponseCode.POST_CREATE_SUCCESS, resDto));
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package com.techeer.fashioncloud.domain.story;

import com.techeer.fashioncloud.domain.story.model.ChatMessage;
import com.techeer.fashioncloud.domain.user.entity.Follow;
import com.techeer.fashioncloud.domain.user.entity.User;
import com.techeer.fashioncloud.domain.user.repository.FollowRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.messaging.simp.SimpMessageSendingOperations;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
@RequiredArgsConstructor
public class ChatService {

private final SimpMessageSendingOperations messagingTemplate;
private final FollowRepository followRepository;

public void sendMessage(ChatMessage message, User sender) {
List<Follow> followers = followRepository.findByToUser_Id(sender.getId());
for (Follow follower : followers) {
messagingTemplate.convertAndSend("/sub/chat/room/" + follower.getFromUser().getId(), message);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package com.techeer.fashioncloud.domain.story.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");
config.setApplicationDestinationPrefixes("/pub");
}

@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/ws-stomp").setAllowedOriginPatterns("*")
.withSockJS();
// registry.addEndpoint("/ws-stomp").setAllowedOrigins("*")
// .setAllowedOriginPatterns("*")
// .withSockJS();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package com.techeer.fashioncloud.domain.story.model;

import com.techeer.fashioncloud.domain.post.dto.response.PostCreateResponseDto;
import lombok.Builder;
import lombok.Getter;
import lombok.Setter;

@Getter
@Setter
@Builder
public class ChatMessage {

// 메시지 타입 : 입장, 채팅
// public enum MessageType {
// ENTER, TALK
// }


private String roomId; // 방번호 /email
private String sender; // 메시지 보낸사람
private PostCreateResponseDto message; // 메시지
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package com.techeer.fashioncloud.domain.story.model;

import lombok.Getter;
import lombok.Setter;

@Getter
@Setter
public class ChatRoom {
private String roomId;
private String name;

public static ChatRoom create(String email) {
ChatRoom chatRoom = new ChatRoom();
chatRoom.roomId = email;
chatRoom.name = email;
return chatRoom;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package com.techeer.fashioncloud.domain.story.repo;

import com.techeer.fashioncloud.domain.story.model.ChatRoom;
import jakarta.annotation.PostConstruct;
import org.springframework.stereotype.Repository;

import java.util.*;

@Repository
public class ChatRoomRepository {

private Map<String, ChatRoom> chatRoomMap;

@PostConstruct
private void init() {
chatRoomMap = new LinkedHashMap<>();
}



public ChatRoom findRoomById(String id) {
return chatRoomMap.get(id);
}

// public ChatRoom createChatRoom(String name) {
// ChatRoom chatRoom = ChatRoom.create(name);
// chatRoomMap.put(chatRoom.getRoomId(), chatRoom);
// return chatRoom;
// }
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
import lombok.Builder;
import lombok.NoArgsConstructor;



@Entity
@Builder
@AllArgsConstructor(access = AccessLevel.PROTECTED)
Expand All @@ -24,4 +26,12 @@ public class Follow extends BaseEntity {
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn()
private User fromUser;

public User getToUser() {
return toUser;
}

public User getFromUser() {
return fromUser;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,8 @@ public interface FollowRepository extends JpaRepository<Follow, Long> {

@Query("SELECT new com.techeer.fashioncloud.domain.user.dto.response.FollowInfoResponseDto(f.fromUser.id, f.fromUser.email, f.fromUser.profileUrl, f.fromUser.username) FROM Follow f WHERE f.toUser.id = ?1")
List<FollowInfoResponseDto> findFollowersByUserId(Long toUserId);

List<Follow> findByToUser_Id(Long toUserId);


}
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ public void follow(User fromUser, Long userId) {
.build();

followRepository.save(follow);
//구독 sub
}

@Transactional
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Excepti
.httpBasic().disable()

.authorizeHttpRequests()
.requestMatchers("/ws/**").permitAll()
.requestMatchers(
"/api/v1/auth/**",
"/api/v1/**", //TODO 임시 설정, 제거필요
Expand Down