항해 57일차 2022.03.07
websocket을 이용해서 서버/클라이언트 통신을 구현해봤다.
메시징 전송을 조금 더 효율적으로 하기 위해 Stomp 프로토콜을 사용해봤다.
pub/sub 구조로 되어 있고 메시지를 발송 / 처리하는 부분이 확실히 정해져 있다.
implementation 'org.webjars:sockjs-client:1.0.2'
implementation 'org.webjars:stomp-websocket:2.3.3'
sockjs는 websocket을 지원하지 않는 낮은 버전의 브라우저에서도 websocket을 사용할 수 있도록 해주는 라이브러리다.
@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").setAllowedOrigins("*")
.withSockJS();
}
}
@Repository
public class ChatRoomRepository {
private Map<String, ChatRoom> chatRoomMap;
@PostConstruct
private void init() {
chatRoomMap = new LinkedHashMap<>();
}
public List<ChatRoom> findAllRoom() {
// 채팅방 생성순서 최근 순으로 반환
List chatRooms = new ArrayList<>(chatRoomMap.values());
Collections.reverse(chatRooms);
return chatRooms;
}
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;
}
}
@RequiredArgsConstructor
@Controller
@RequestMapping("/chat")
public class ChatRoomController {
private final com.spring.wschat.repo.ChatRoomRepository chatRoomRepository;
// 채팅 리스트 화면
@GetMapping("/room")
public String rooms(Model model) {
return "/chat/room";
}
// 모든 채팅방 목록 반환
@GetMapping("/rooms")
@ResponseBody
public List<ChatRoom> room() {
return chatRoomRepository.findAllRoom();
}
// 채팅방 생성
@PostMapping("/room")
@ResponseBody
public ChatRoom createRoom(@RequestParam String name) {
return chatRoomRepository.createChatRoom(name);
}
// 채팅방 입장 화면
@GetMapping("/room/enter/{roomId}")
public String roomDetail(Model model, @PathVariable String roomId) {
model.addAttribute("roomId", roomId);
return "/chat/roomdetail";
}
// 특정 채팅방 조회
@GetMapping("/room/{roomId}")
@ResponseBody
public ChatRoom roomInfo(@PathVariable String roomId) {
return chatRoomRepository.findRoomById(roomId);
}
}