2021. 11. 3. 19:14ㆍ개발/nodejs
로드밸런싱을 위해 서버를 여러개 두었더니 채팅 기능에 문제가 생겼다.
socket.io-redis 모듈을 사용하여 해결하였다.
사실 수정된 부분도 별로 없고 한데, 별 이유로 삽질하느라 시간을 너무 많이 잡아먹어 되풀이 하지 않도록 적어본다.
우선 레디스를 먼저 설치해주어야 한다.
난 도커로 설치하였다.
1. Dockerfile 및 redis.conf 작성
- Dockerfile
FROM redis
COPY redis.conf /etc/redis/redis.conf
CMD ["redis-server", "/etc/redis/redis.conf"]
- redis.conf
bind 0.0.0.0
기본으로 로컬에서만 접근 가능하도록 되어있으니 설정 해주어야 한다.
2. 빌드 및 컨테이너 생성/실행
Dockerfile 과 redis.conf 파일이 있는 디렉토리에서..
sudo docker build -t 이미지명:태그
sudo docker build -t dockerId/redis:tag .
sudo docker create --name 컨테이너명 -p 외부포트:내부포트 이미지명:태그
sudo docker create --name redis -p 6379:6379 dockerId/redis:tag
sudo docker start redis
레디스는 기본 6379 포트를 사용한다.
다른 포트를 사용하고 싶을경우 ( 예 1234 ) 위의 redis.conf 에 port 1234 를 추가해주고 그에 맞게 컨테이너를 만들어주면 된다.
( 근데 외부에서 막 붙는게 걱정될 경우 컨테이너 생성할 때 외부포트를 다른걸로 하면 될것같다 )
3. socket.io / socket.io-redis 모듈 설치
npm i --save socket.io
npm i --save socket.io-redis
2. 서버 설정파일 수정
- www.js
let app = require('../app');
let server = http.createServer(app);
// 채팅 관련 부분을 따로 빼 모아두었다.
let socket = require('./socket');
...
let io = require('socket.io')(server);
socket(io);
...
3. 채팅 처리 관련 파일 수정
- socket.js ( 서버사이드 )
let redis = require('socket.io-redis');
...
module.exports = function (io) {
// 당연하지만 해당 서버에 레디스가 설치 되어있어야 한다.
io.adapter(redis({host: 'xxx.xxx.xxx.xx', port: 6379}));
// 커넥트
io.sockets.on('connection', (socket) => {
// 메시지 수신 및 전달
socket.on('message', (data) => {
// 간혹 데이터가 문자열로 넘어오는 경우가 있어 처리
if (typeof data == typeof '') data = JSON.parse(data);
// 같은 방 사람에게만 발송
socket.broadcast.to(`${data.room_id}`).emit('message', (data))
});
});
}
...
서버주소, 포트 잘 확인해주어야 한다. 서버에 오타난거 모르고 다른곳에서 원인 찾다가 정말 많은 시간을 버렸다.
- chat.js ( 클라이언트 )
<script defer src="/socket.io/socket.io.js"></script>
<script>
// 로컬에서만 테스트 할 경우 값을 비워도 되지만, 그게 아닐경우 HOST:PORT 를 입력해야된다
var socket = io.connect("xxx.xxx.xx.xx:port");
socket.on('message', function (data) {
/*
수신받은 메시지 처리
*/
});
// 메시지 전송
socket.emit('message', {
"nickname": nickname,
"content": val,
"room_id": room_id
});
});
</script>
로드밸런싱 하기 전에는 host:port 를 적지 않아도 잘 작동했던것 같은데.. 뭔가 이상하지만 무튼 적어주니 정상 작동하였다.
여러개로 나누었던 서버 끼리의 채팅은 물론, 로컬에서 실행한 서버도 메시지가 공유되었다.
+ 레디스 연결시 timeout 이 발생한다면 포트 열려있는지 꼭 확인해보고, 주소 잘 적었는지도 확인해보자
'개발 > nodejs' 카테고리의 다른 글
[nodejs] html to image 로 이미지에 글자 및 이미지 넣기 / 한글 깨짐 오류 해결 (0) | 2024.06.26 |
---|---|
[Mac m1] canvas node package 설치 오류 (1) | 2024.06.04 |
[Mac] nvm / node.js 설치 (1) | 2024.06.04 |
nodejs/docker 환경에서 파일 업로드 이슈 해결 (0) | 2021.11.02 |
nodejs / tensorflow.js 참고 (0) | 2021.10.25 |