생각을 해보자
채팅하는 곳에 사용자들이 들어오게 된다면 우리는 어떻게 판을 짜줘야 할까?
채팅이 이뤄지는 환경이란 무엇인가? 채팅 기능 구현 (1)에서 언급했듯이 우리는 sockJS와 stomp를 사용한다. 왜? DB에 서로 메시지 쌓아가면서 읽고 쓰기엔 시간이 너무 오래걸리거든
그래서 우리는 요청을 매번 보내는게 아니라 connection을 유지해서 양방향 통신 또는 데이터 전송이 가능하도록, 그래서 빠르고 실시간으로 정보 전달을 위해 웹소켓 기술을 사용하는 것이다.
useEffect(() => {
}, [])
useEffect(() => {
// SockJS 및 STOMP 클라이언트 연결 설정
const socket = new SockJS('백엔드에서 정해준 API 경로')
const stompClient = StompJs.over(socket)
}, [])
useEffect(() => {
// SockJS 및 STOMP 클라이언트 연결 설정
const socket = new SockJS('백엔드에서 정해준 API 경로')
const stompClient = StompJs.over(socket)
// TOKEN은 로그인 Access 토근이 필요하여 Authorization 필드의 값으로 넣어주었다.
stompClient.connect({ Authorization: TOKEN }, () => {
const roomNum = 1 // 방 번호는 예시로 설정
stompClient.subscribe(`/sub/message/${roomNum}`, message => {
// 새로운 메시지 도착 시 실행되는 콜백 함수
const newMessage = JSON.parse(message.body)
setMessages(prevMessages => [...prevMessages, newMessage])
})
})
}, [])
const sendMessage = () => {
const socket = new SockJS('백엔드에서 정해준 API 경로')
const stompClient = StompJs.over(socket)
const roomNum = 1 // 메세지 보낼 방 번호 통일
const newMessage = {
// 해당 객체는 백엔드와 협의 하에 이뤄진 body 예시일 뿐입니다.
content: input, // 화면에 메세지 타이핑시 input에 저장되도록 설정 해 놓았다.
sender: '요리사', // 닉네임 예시
}
stompClient.send(
`백엔드에서 정해준 API 경로`,
{},
JSON.stringify({
// 해당 객체는 백엔드와 협의 하에 이뤄진 body 예시일 뿐입니다.
roomId: roomNum,
message: newMessage.content,
writer: newMessage.sender,
messageType: 'CHAT',
})
)
setInput('')
}
이렇게 1차적으로 통신에 필요한 구색을 갖춘 듯 하지만
메세지가 발송되지 않는다.
개발자 모드에서 cosole 쪽에 이런 메세지가 보내지기는 하는데
>>> SEND
destination:/pub/message/1
content-length:69
{"roomId":1,"message":"dd","writer":"요청자","messageType":"CHAT"}
정작 DB에는 저장되지 않았고 ( 우리 프로젝트는 실시간 채팅을 위한 통신의 경우를 제외하고 또 다른 경우의 수를 위해서 DB에 다가도 채팅을 저장하기로 했다.)
main.js:161 Uncaught Error: InvalidStateError: The connection has not been established yet
at SockJS.send (main.js:161:11)
at Client2._transmit (stomp.js:159:26)
at Client2.send (stomp.js:366:19)
at sendMessage (DmTest2.tsx:49:17)
at HTMLUnknownElement.callCallback2 (react-dom.development.js:4164:14)
at Object.invokeGuardedCallbackDev (react-dom.development.js:4213:16)
at invokeGuardedCallback (react-dom.development.js:4277:31)
at invokeGuardedCallbackAndCatchFirstError (react-dom.development.js:4291:25)
at executeDispatch (react-dom.development.js:9041:3)
at processDispatchQueueItemsInOrder (react-dom.development.js:9073:7)
이런 붉디 붉은 에러를 발생했다.
해결 과정은 다음 글에서 ...