일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
- react native font
- s3 upload
- 문자열 대소문자 구별
- 에러
- react native
- GIT
- react native CLI
- 문자열 대소문자
- 리액트 네이티브 에러
- react native 개발
- 백준
- aws bucket 정책
- PongWorld
- error
- 리엑트 네이티브 아이콘
- react native 세팅
- Project
- firebase 라이브러리
- Access Key 생성
- fire base
- js
- img upload
- babel.config.js
- AWS Access Key
- 리액트 네이티브
- React
- react native picker
- 리액트
- AWS
- Next.js
- Today
- Total
밝을희 클태
WebSocket 이 닫히면 재연결을 해보자 본문
프로젝트를 진행 중 WebSocket이 닫히는 현상이 생겼다.
채팅을 구현하는데 채팅방에 들어가지 않고 메세지를 입력해서 WebSocket에 Send 를 하면 오류가 나서 웹소켓이 닫혀버린다. 이거는 채팅방에 들어가지 않았을 때 그냥 채팅을 입력하지 못하게 하면 그만이지만 이 외에도 WebSocket이 닫혀버린 채로 있다면 싱글톤 패턴으로 WebSocket을 사용하고 있기 때문에 나중에 큰 문제가 될 수 있기 때문에 닫히면 다시 연결하는 로직을 구현을 하기로 했다.
첫 번째 방식
import BaseWebSocket from './BaseWebSocket.js';
import {getToken, refreshAccessToken} from '../tokenManager.js';
import {checkConnectionSocket} from '../webSocketManager.js';
class ConnectionSocket extends BaseWebSocket {
async connect(url) {
...
this.ws.onclose = async () => {
console.log('Connection WebSocket 닫힘');
this.connect(url);
};
...
}
}
const cws = ConnectionSocket.getInstance();
export default cws;
처음에는 단순히 WebSocket이 닫히면 WebSocket Class 내부에서 onclose 이벤트가 발생하면 다시 connect() 함수를 호출하여 연결하게 했다.
이렇게 하니까 WebSocket이 끊겨도 다시 연결은 잘 됐다. 그런데 문제가 있다. 웹소켓 연결은 다시 잘 됐지만 아무 의미가 없다 이벤트를 아무것도 설정을 해주지 않고 연결만 돼서 쓸모가 없는 WebSocket이 됐다.
두 번째 방식
import cws from './WebSocket/ConnectionSocket.js';
import {refreshAccessToken, getToken} from './tokenManager.js';
let tempHandler = null;
export const checkConnectionSocket = async handler => {
if (handler) tempHandler = handler;
return new Promise(async (resolve, reject) => {
if (!cws.getWS()) {
try {
await connectionSocketConnect(handler);
console.log('connectionSocket 재연결!');
resolve();
} catch (error) {
console.log('checkConnectionSocket Error : ', error);
reject(error);
}
} else if (cws.getWS().readyState === WebSocket.CLOSED) {
try {
await connectionSocketConnect(tempHandler);
resolve();
} catch (error) {
console.log('checkConnectionSocket Error : ', error);
reject(error);
}
} else resolve();
cws.setEvent(handler);
});
};
export const connectionSocketConnect = async handler => {
if (!getToken().length) await refreshAccessToken();
await cws.connect('ws://127.0.0.1:8000/ws/connection/');
cws.setEvent(handler);
};
위 코드는 WebSocket 을 관리해 주는 코드인데
if (handler) tempHandler = handler;
return new Promise(async (resolve, reject) => {
if (!cws.getWS()) {
try {
await connectionSocketConnect(handler);
console.log('connectionSocket 재연결!');
resolve();
} catch (error) {
console.log('checkConnectionSocket Error : ', error);
reject(error);
}
}
이 부분은 전에 새로고침이 일어났을 때 아예 WebSocket이 끊겨 버리기 때문에 새로 연결하는 로직을 추가해 주었고 이번에 추가된 부분은
if (handler) tempHandler = handler;
...
else if (cws.getWS().readyState === WebSocket.CLOSED) {
try {
await connectionSocketConnect(tempHandler);
resolve();
} catch (error) {
console.log('checkConnectionSocket Error : ', error);
reject(error);
}
}
이 코드이다 일단 tempHandler 변수를 전역으로 두어서 처음에 정상적으로 WebSocket 을 연결할 때 handler(WebSocket Event Handler) 함수를 전역 변수에 저장을 해두고, WebSocket error 로 WebSocket 이 닫히면
WebSocket Class 에서 connet() 함수 대신 checkConnectionSocket() 함수를 호출해서 연결과 동시에 내가 이전에 사용했던 Event 를 함께 등록을 해준다.
import BaseWebSocket from './BaseWebSocket.js';
import {getToken, refreshAccessToken} from '../tokenManager.js';
import {checkConnectionSocket} from '../webSocketManager.js';
class ConnectionSocket extends BaseWebSocket {
async connect(url) {
...
this.ws.onclose = async () => {
console.log('Connection WebSocket 닫힘');
await checkConnectionSocket();
};
...
}
}
const cws = ConnectionSocket.getInstance();
export default cws;
WebSocket 이 일부러 닫히는 상황을 만들어 테스트 결과 닫힘과 동시에 새로 연결이 되고 이벤트까지 잘 작동해서 사이트가 제대로 동작을 했다!
하지만 여기에도 문제점이 있다 지금 WebSocket 이 닫히면 따로 Conut 나 Delay 를 주지 않아서 무한루프에 빠질거나 사이트에 부담이 갈 수도 있다. 이건 추후에 수정을 해야겠다
'PongWorld 프로젝트' 카테고리의 다른 글
탁구채 애니메이션 최적화: setInterval vs requestAnimationFrame, position vs transform (1) | 2024.04.05 |
---|---|
인증되지 않은 유저 접근 막기 (0) | 2024.04.02 |
탁구채 속도가 환경에 따라 다르게 움직임(requestAnimationFrame) (0) | 2024.03.23 |
같은 경로의 이동을 막자 (0) | 2024.03.14 |
싱글톤 패턴을 활용한 중앙 집중식 WebSocket 관리 방식 (0) | 2024.03.11 |