feat(user-creator-chat): WebSocket Redis room broker를 추가한다
This commit is contained in:
@@ -14,6 +14,7 @@ import org.springframework.data.redis.connection.RedisStandaloneConfiguration
|
||||
import org.springframework.data.redis.connection.lettuce.LettuceClientConfiguration
|
||||
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory
|
||||
import org.springframework.data.redis.core.RedisTemplate
|
||||
import org.springframework.data.redis.listener.RedisMessageListenerContainer
|
||||
import org.springframework.data.redis.repository.configuration.EnableRedisRepositories
|
||||
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer
|
||||
import org.springframework.data.redis.serializer.RedisSerializationContext
|
||||
@@ -63,6 +64,13 @@ class RedisConfig(
|
||||
return redisTemplate
|
||||
}
|
||||
|
||||
@Bean
|
||||
fun redisMessageListenerContainer(redisConnectionFactory: RedisConnectionFactory): RedisMessageListenerContainer {
|
||||
val container = RedisMessageListenerContainer()
|
||||
container.setConnectionFactory(redisConnectionFactory)
|
||||
return container
|
||||
}
|
||||
|
||||
@Bean
|
||||
fun cacheManager(redisConnectionFactory: RedisConnectionFactory): RedisCacheManager {
|
||||
val defaultCacheConfig = RedisCacheConfiguration.defaultCacheConfig()
|
||||
|
||||
@@ -0,0 +1,65 @@
|
||||
package kr.co.vividnext.sodalive.v2.usercreatorchat.websocket
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper
|
||||
import org.springframework.data.redis.connection.Message
|
||||
import org.springframework.data.redis.connection.MessageListener
|
||||
import org.springframework.data.redis.core.StringRedisTemplate
|
||||
import org.springframework.data.redis.listener.PatternTopic
|
||||
import org.springframework.data.redis.listener.RedisMessageListenerContainer
|
||||
import org.springframework.stereotype.Component
|
||||
import org.springframework.web.socket.TextMessage
|
||||
import org.springframework.web.socket.WebSocketSession
|
||||
import java.nio.charset.StandardCharsets
|
||||
|
||||
@Component
|
||||
class UserCreatorChatRoomMessageBroker(
|
||||
private val stringRedisTemplate: StringRedisTemplate,
|
||||
private val sessionRegistry: UserCreatorChatWebSocketSessionRegistry,
|
||||
private val objectMapper: ObjectMapper,
|
||||
listenerContainer: RedisMessageListenerContainer
|
||||
) : MessageListener {
|
||||
init {
|
||||
listenerContainer.addMessageListener(this, PatternTopic("$ROOM_CHANNEL_PREFIX:*"))
|
||||
}
|
||||
|
||||
fun publish(roomId: Long, memberId: Long, payload: String) {
|
||||
val message = UserCreatorChatRoomPublishedMessage(
|
||||
roomId = roomId,
|
||||
memberId = memberId,
|
||||
payload = payload
|
||||
)
|
||||
stringRedisTemplate.convertAndSend(roomChannel(roomId), objectMapper.writeValueAsString(message))
|
||||
}
|
||||
|
||||
override fun onMessage(message: Message, pattern: ByteArray?) {
|
||||
val published = objectMapper.readValue(
|
||||
String(message.body, StandardCharsets.UTF_8),
|
||||
UserCreatorChatRoomPublishedMessage::class.java
|
||||
)
|
||||
sessionRegistry.findSessions(published.roomId, published.memberId)
|
||||
.filter { session -> session.isOpen }
|
||||
.forEach { session -> sendMessage(session, published.payload) }
|
||||
}
|
||||
|
||||
private fun sendMessage(session: WebSocketSession, payload: String) {
|
||||
try {
|
||||
session.sendMessage(TextMessage(payload))
|
||||
} catch (_: Exception) {
|
||||
sessionRegistry.remove(session.id)
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val ROOM_CHANNEL_PREFIX = "v2:user-creator-chat:ws:room"
|
||||
|
||||
fun roomChannel(roomId: Long): String {
|
||||
return "$ROOM_CHANNEL_PREFIX:$roomId"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
data class UserCreatorChatRoomPublishedMessage(
|
||||
val roomId: Long,
|
||||
val memberId: Long,
|
||||
val payload: String
|
||||
)
|
||||
Reference in New Issue
Block a user