서버 배포 후 소켓 연결 시 에러메시지 출력
원인
결과
백엔드 쪽에서 정확한 원인을 찾지 못했다고 해서 다음에 다시 찾아보기로 했다. 그래도 일단 문제는 해결 되었다.
알림
로그인 시 모든 유저를 공통된 room(PublicRoom)에 넣는다.
채팅을 하는 1:1 room에(ChatRoom) 입장해서 메시지 입력 시, 상대방이 ChatRoom에 들어와 있지 않고 PublicRoom에 들어와 있을 때 해당하는 유저를 찾은 후 알림 보냄
브라우저가 꺼졌을 때 unsubscribe
실시간 알람 기능을 구현 하기 위해 로그인 시 메인 페이지에 들어왔을 때 모든 유저를 공통된 room에 연결 시킨다.
문제점
새로고침 시 /autu 로 get요청을 보내서 user정보를 받아 오는데 받아오기 전에 소켓이 먼저 연결 되어서 userEmail이 들어오지 않음.
항상 소켓에 접속해 있는거라면 모든 컴포넌트를 감싸고 있는 index.html이나 index.js에 로그인 시 소켓에 연결되게 하면 되지 않을까 라는 생각이 들어서 일단은 app.js도 모든 컴포넌트를 감싸고 있으니 App.js에 소켓과 연결되는 로직을 작성해 보았다.
import StompJs from 'stompjs';
import SockJS from 'sockjs-client';
import { useSelector } from 'react-redux';
import { getToken } from '../utils/auth';
// App.js
const baseURL = process.env.REACT_APP_SERVER_URI; //서버 주소
const userInfo = useSelector((state) => state.user);
const sock = new SockJS(`${baseURL}/ws-stomp`);
const ws = StompJs.over(sock);
const token = getToken();
// 소켓 연결 함수
const wsConnectSubscribe = React.useCallback(() => {
if (!token) {
return null;
}
try {
ws.connect({}, () => {
ws.subscribe(
`/user/sub/user`,
{},
{ token, userEmail: userInfo.email },
);
});
} catch (error) {
console.log(error);
}
}, [ws]);
// token이 있으면 소켓 연결
React.useEffect(() => {
if (!token) {
return null;
}
wsConnectSubscribe();
}, [wsConnectSubscribe, userInfo, token]);
// 로그인을 해도 소켓에 연결이 되지 않아 의존성 배열을 추가 했으나 동작하지 않음
// wsConnectSubscribe을 의존성 배열에 추가하면 새로고침시 subscribe 두번 실행 됨
위와 같은 생각에 헤더는 모든 페이지에 항상 있으니 헤더에 적용을 시도 해보았지만 로그인 시에 useEffect가 실행 되지 않았다.
왜?
로그인 페이지에서 로그인 버튼을 누를 때 소켓에 연결이 된다는 생각으로 로직을 작성했다.
// Login.js
const wsConnectSubscribe = (userEmail, token) => {
console.log('토큰 있냐? ===> ', token);
if (!token) {
console.log('토큰 업쩡');
return null;
}
try {
ws.connect({}, () => {
ws.subscribe(`/user/sub/user`, {}, { token, userEmail });
});
} catch (error) {
console.log(error);
}
};
// 로그인 버튼 클릭 시 실행
<form
onSubmit={handleSubmit(async (loginInfo) => {
console.log('로그인 인포 ===>', loginInfo);
await dispatch(loginToServer(loginInfo));
const token = getToken();
console.log('커넥트 실행');
wsConnectSubscribe(loginInfo.email, token);
console.log('히스토리 푸시');
// history.push('/');
})}
>
...
</form>
??????....
왜 소켓 연결이 안될까?
근데 로그인창에서 코드를 작성 하다가 든 생각인데 결국 유저가 메인페이지에서 새로고침을 하면 소켓에 재연결이 안될 것 같아 결국 메인페이지로 다시 돌아왔다..
import StompJs from 'stompjs';
import SockJS from 'sockjs-client';
import { useSelector } from 'react-redux';
import { getToken } from '../utils/auth';
// App.js
const baseURL = process.env.REACT_APP_SERVER_URI; //서버 주소
const userInfo = useSelector((state) => state.user);
const sock = new SockJS(`${baseURL}/ws-stomp`);
const ws = StompJs.over(sock);
const token = getToken();
// 소켓 연결 함수
const wsConnectSubscribe = React.useCallback(() => {
if (!token) {
return null;
}
try {
ws.connect({}, () => {
ws.subscribe(
`/user/sub/user`,
{},
{ token, userEmail: userInfo.email },
);
});
} catch (error) {
console.log(error);
}
}, [ws]);
// token이 있으면 소켓 연결
React.useEffect(() => {
if (!token) {
return null;
}
wsConnectSubscribe();
}, []);
// 처음 한번만 연결, 이 다음은 일단 여기 넘어가고 생각해야겠다.
user A
, user B
는 Grab
되어있다.
user A
는 접속 중, user B
는 접속 중이 아니다.
user A
는 user B
와의 채팅창에서 메시지를 남겼다.
그 이후에 user B
가 사이트에 접속을 했다.
user B
가 로그인 했을 때 받는 Response
의 alarm은 true
아까 리스폰스 보고 동작 되는줄 알았는데 다시 해보니까 안된다 ㅜ