์ฝ์ง๋จ
TIL 17๋ฒ์งธ ๋ณธ๋ฌธ
๐ ์ค๋ ํ ๊ฒ
โ OSI 7 ๊ณ์ธต ํ์
โ Redis Pub / Sub ์ฌ์ฉํ์ฌ ์คํ๋ง๋ถํธ์์ Publisher , Subcribe , Topic ๋ถ๋ถ ๊ตฌํํด๋ณด๊ธฐ
โ ํ์ฌ ํ์ ์ค์ธ ํ๋ก์ ํธ ๋ฌดํ ๋๋๊ธ ์์ ๊ฐ์ด ์์์๋ ๋ถ๊ตฌํ๊ณ NULL์ด ์ฐํ๋ ํ์ ํฝ์ค
โ ์๊ณ ๋ฆฌ์ฆ 2๋ฌธ์ ํ๊ธฐ
๋ฉ์ธ์ง๋ฅผ ์ ๋ ฅํ๊ฑฐ๋, ์ ์ฅํ๊ฒ๋๋ฉด RedisPublisher.publish ๋ก ๋ฐํ
@RequiredArgsConstructor
@Controller
public class ChatController {
private final RedisPublisher redisPublisher;
private final ChatRoomRepository chatRoomRepository;
/**
* websocket "/pub/chat/message"๋ก ๋ค์ด์ค๋ ๋ฉ์์ง์ ์ฒ๋ฆฌํ๋ค.
*/
@MessageMapping("/chat/message")
public void message(ChatMessage message) {
if (ChatMessage.MessageType.ENTER.equals(message.getType())) {
chatRoomRepository.enterChatRoom(message.getRoomId());
message.setMessage(message.getSender() + "๋์ด ์
์ฅํ์
จ์ต๋๋ค.");
}
// Websocket์ ๋ฐํ๋ ๋ฉ์์ง๋ฅผ redis๋ก ๋ฐํํ๋ค(publish)
redisPublisher.publish(chatRoomRepository.getTopic(message.getRoomId()), message);
}
}
์์์ ์ฌ์ฉ์๊ฐ ์ ๋ ฅํ ๋ฉ์ธ์ง๋ฅผ ํด๋น Redis์ ํ ํฝ์ฑ๋์ ๋ฐํ์ํ๋ฉด
@RequiredArgsConstructor
@Service
public class RedisPublisher {
private final RedisTemplate<String,Object> redisTemplate;
public void publish(ChannelTopic topic, ChatMessage message){
redisTemplate.convertAndSend(topic.getTopic(),message);
}
}
* Redis์์ ๋ฉ์์ง๊ฐ ๋ฐํ(publish)๋๋ฉด ๋๊ธฐํ๊ณ ์๋ onMessage๊ฐ ํด๋น ๋ฉ์์ง๋ฅผ ๋ฐ์ ์ฒ๋ฆฌํ๋ค.
@Slf4j
@RequiredArgsConstructor
@Service
public class RedisSubscriber implements MessageListener {
private final ObjectMapper objectMapper;
private final RedisTemplate redisTemplate;
private final SimpMessageSendingOperations messagingTemplate;
/**
* Redis์์ ๋ฉ์์ง๊ฐ ๋ฐํ(publish)๋๋ฉด ๋๊ธฐํ๊ณ ์๋ onMessage๊ฐ ํด๋น ๋ฉ์์ง๋ฅผ ๋ฐ์ ์ฒ๋ฆฌํ๋ค.
*/
@Override
public void onMessage(Message message, byte[] pattern) {
try {
// redis์์ ๋ฐํ๋ ๋ฐ์ดํฐ๋ฅผ ๋ฐ์ deserialize
String publishMessage = (String) redisTemplate.getStringSerializer().deserialize(message.getBody());
// ChatMessage ๊ฐ์ฑ๋ก ๋งตํ
ChatMessage roomMessage = objectMapper.readValue(publishMessage, ChatMessage.class);
// Websocket ๊ตฌ๋
์์๊ฒ ์ฑํ
๋ฉ์์ง Send
messagingTemplate.convertAndSend("/sub/chat/room/" + roomMessage.getRoomId(), roomMessage);
} catch (Exception e) {
log.error(e.getMessage());
}
}
}
Stomp ๋ฅผ ์ฌ์ฉํ๋ฉด ํธํ์ ์ ๊ฐ๊ฐ ๋ฉ์ธ์ง๋ฅผ ์ ์กํ๋ ๋งค์ฒด, ๋ฐ๋ ๋งค์ฒด์ ์ญํ ์ด ์ ํด์ ธ์๋ค๋ ๊ฒ์ด๋ค. (PUB/SUB)
(๋ธ๋ก์ปค๋ผ๋ ์ค๊ฐ ๋งค๊ฐ์ฒด๋ฅผ ํตํด ๋ฐ์ดํฐ๋ฅผ ์กฐ์จ ํ ์์์ ํ์ฌ ์์ ์ฝ๋์์๋ REDIS ๊ฐ ๋ธ๋ก์ปค๋ผ๊ณ ์๊ฐํ๋ฉด๋จ)
๐คฆ ๊ทผ ๋ช์ผ๊ฐ ์ฒ์ ์ ํด๋ณด๋ Socket ์ด๋ผ๋ ๊ฐ๋ ๊ณต๋ถ๋ฅผ ํ๊ณ ๊ตฌํํ๋๋ผ ์ ์ ์ด์๋ค.. ์ด๋ค ์ผ์ด๋ ์ฒ์์ ํญ์ ํ๋ ๊ฒ ๊ฐ๋ค. ์๋ ๋ช์ผ ์ ๊น์ง socket์ด๋ผ๋ ๋จ์ด์กฐ์ฐจ ๋ชฐ๋๋๋ฐ ํ์ฌ ํ๋ก์ ํธ์ ์ ์ฉ ํ ์ผ์ด ์๊ฒจ ๊ธํ๊ฒ ๊ณต๋ถ์ค์ด๋ค.
์๋ ์ฐ๋ฆฌ๊ฐ ์์ฃผ ์ฌ์ฉํ๋ HTTP ํน์ง์ ๋ฐ์ด์ค ํต์ ์ผ๋ก ํด๋ผ์ด์ธํธ๊ฐ ์์ฒญ์ ํ๊ณ ์๋ฒ๊ฐ ์์ฒญ์ ๋ฐ์ ์๋ต์ํ๋ฉด
์ฐ๊ฒฐ์ด ๋๊ธฐ๋ Statelessํ ํ๋กํ ์ฝ์ด๋ค.
ํ์ง๋ง ์ฑํ ๊ธฐ๋ฅ์ ์ด๋ ๊ฒ ํ๋ฒ ์ฌ์ดํด์๋๊ณ ์ฐ๊ฒฐ์ด ๋๊ธฐ๊ณ ๋ฅผ ๋ฌดํ ๋ฐ๋ณตํ๋ฉด ํฐ ์์ ์ํด์ด๋ค. ์ด๋ฅผ ๋ณด์ํ๊ธฐ ๋์จ ํ๋กํ ์ฝ์ด Socket์ธ๋ฐ, ์ ์ด์ค ํต์ ์ด์, Statefulํ๋ฉฐ ์ฒ์ Socket ์ฐ๊ฒฐ์ ํ ๋ ๋นผ๊ณ ๋ ํญ์ ์ฐ๊ฒฐ๋์ด ์๋ ์ํ์ ํ๋กํ ์ฝ์ด๋ค. (์ฑํ ์ ์ ํฉํ) ์ผ๋ฐ ์์บฃ๋ง์ ๋ธ๋ผ์ฐ์ ์์ ํธํ๋์ง ์๋ ํ์์ด ๋ฐ์ํด ์คํ๋ง์ ์ฉ Socket์ธ SockJs๋ฅผ ์ฌ์ฉํ๊ณ ์๊ณ ์ด์ ์ฑํ ๊ธฐ๋ฅ์ ์กฐ๊ธ๋ ๋ฐ์ ์ํค๊ณ ํธํ๊ฒ ์ฌ์ฉํ๊ธฐ์ํ Stomp๋ฅผ ์ฌ์ฉํด์ Pub/Sub ๊ธฐ๋ฅ์ ์ฌ์ฉํ๋ค.
'TIL' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
TIL 19์ผ์ฐจ (0) | 2022.01.07 |
---|---|
TIL 18๋ฒ์งธ (0) | 2022.01.05 |
TIL 16๋ฒ์งธ (0) | 2022.01.01 |
TIL 15๋ฒ์งธ (0) | 2021.12.30 |
TIL 14๋ฒ์งธ (0) | 2021.12.29 |