반응형
목차
- SpringBoot에서 STOMP로 채팅 애플리케이션 만들기 (1)
- SpringBoot에서 STOMP로 채팅 애플리케이션 만들기 (2) - 현재 게시글
- SpringBoot에서 STOMP로 채팅 애플리케이션 만들기 (3)
springboot-web 관련 의존성은 추가되어있다는 것을 가정으로 글을 작성하니 참고 부탁드립니다.
1. 채팅방 관리를 위한 Entity 및 Component 추가
여기선 Repository에 별도 DataSource를 연결하지 않고 memory 상에 Map으로 관리해주었다.
// ChatRoom.kt
data class ChatRoom(
val name: String
) {
val id: String
get() = "room_$name"
}
// ChatRoomRepository.kt
@Repository
class ChatRoomRepository {
private val chatRooms = LinkedHashMap<String, ChatRoom>()
fun findAllRoom(): List<ChatRoom> {
return chatRooms.values.toList()
}
fun findById(id: String): ChatRoom {
return chatRooms[id]!!
}
fun createRoom(name: String): ChatRoom {
return ChatRoom(
name = name
).also {
chatRooms[it.id] = it
}
}
}
// ChatRoomService.kt
@Service
class ChatRoomService(
private val chatRoomRepository: ChatRoomRepository
) {
fun findAllRoom(): List<ChatRoom> {
return chatRoomRepository.findAllRoom()
}
fun findById(id: String): ChatRoom {
return chatRoomRepository.findById(id)
}
fun createRoom(name: String): ChatRoom {
return chatRoomRepository.createRoom(name)
}
}
2. SpringBoot websocket 의존성 추가
dependencies {
implementation("org.springframework.boot:spring-boot-starter-websocket")
}
해당 라이브러리에는 STOMP를 비롯한 소켓 통신을 위한 여러 구현체가 존재한다.
3. WebSocketConfig 생성
@Configuration
@EnableWebSocketMessageBroker
class WebSocketConfig : WebSocketMessageBrokerConfigurer {
override fun registerStompEndpoints(registry: StompEndpointRegistry) {
registry.addEndpoint("/ws/chat")
.setAllowedOriginPatterns("*")
.withSockJS()
}
override fun configureMessageBroker(registry: MessageBrokerRegistry) {
registry.enableSimpleBroker("/sub")
}
}
- STOMP 엔드포인트를 /ws/chat 으로 설정 해주고, 어느 곳에서나 접근 가능하게 해둔 뒤 SocketJS를 이용해 통신할 것임을 명시해준다.
- 브로커(여기선 in-memory broker)에게 /sub 이라는 prefix로 오는 요청을 수신할 것을 등록해준다.
4. Client와 통신 시 사용할 Mapping 정보 등록
// dto.kt
data class ChatRoomDto(
val id: String
)
data class ChatDto(
val type: Type,
val sender: String,
val message: String
) {
val createdAt: Long = LocalDateTime.now().toEpochMillis()
enum class Type {
ENTER, COMMENT
}
}
internal fun ChatRoom.toDto() = ChatRoomDto(
id = id
)
private fun LocalDateTime.toEpochMillis(zoneId: ZoneId = ZoneOffset.UTC): Long = this.atZone(zoneId).toInstant().toEpochMilli()
// ChatRoomRestController.kt
@RestController
class ChatRoomRestController(
private val chatRoomService: ChatRoomService
) {
/**
* 클라이언트의 /pub 요청을 받아 /sub 에게 보낸다
* 실제론 해당 블록 내에 채팅 기록 저장 등의 로직이 필요하다
*/
@MessageMapping("/pub/chat/room/{roomId}")
@SendTo("/sub/chat/room/{roomId}")
fun message(@DestinationVariable roomId: String, dto: ChatDto): ChatDto {
return dto
}
/**
* 채팅방 생성
*/
@PostMapping(
value = ["/api/v1/chat/room"],
produces = [MediaType.APPLICATION_JSON_VALUE]
)
fun createRoom(@RequestParam name: String): ChatRoomDto {
return chatRoomService.createRoom(name).toDto()
}
/**
* 등록된 채팅방 전체 조회
*/
@GetMapping(
value = ["/api/v1/chat/room"],
produces = [MediaType.APPLICATION_JSON_VALUE]
)
fun findAllRoom(): List<ChatRoomDto> {
return chatRoomService.findAllRoom().map {
it.toDto()
}
}
/**
* 채팅방 정보 조회
*/
@GetMapping(
value = ["/api/v1/chat/room/{roomId}"],
produces = [MediaType.APPLICATION_JSON_VALUE]
)
fun roomInfo(
@PathVariable roomId: String
): ChatRoom {
return chatRoomService.findById(roomId)
}
}
다음은 구현한 서버에 맞는 클라이언트를 만들어 볼 차례다.
다음 편에 계속 - SpringBoot에서 STOMP로 채팅 애플리케이션 만들기 (3)
반응형
☕️ Networking
기술 직군의 기술적인 교류, 커리어 이야기, 직군 무관 네트워킹 모두 환영합니다!
위클리 아카데미 오픈 채팅방(비밀번호: 9323)
kakaotalk: https://open.kakao.com/o/gyvuT5Yd