이번 글에서는 Node.js와 Socket.IO를 통해 기본적인 채팅 애플리케이션을 구축하는 방법을 소개합니다. 이어 Redis Pub/Sub 메세징 기능을 적용해 Clustering 모드로 애플리케이션을 확장하는 법까지 알아보겠습니다.
- Socket.IO 기반의 채팅 애플리케이션 구축
- Redis의 Publish/Subscribe 기능 활용
- PM2를 활용한 Clustering 모드 적용
Socket.IO 기반의 채팅 사이트 구축
1. Socket.IO Demo Project 받기
Socket.IO 공식 데모 프로젝트를 git clone합니다.
[guser@nodejs ~]$ git clone https://github.com/socketio/socket.io
2. WORK_DIR 변경
(가비아 Node.js 호스팅을 이용하지 않는 경우, 아래 단계는 생략합니다.)
[guser@nodejs ~]$ vi .bashrc
[변경 전]
export WORK_DIR="/web"
[변경 후]
WORK_DIR에 프로젝트 경로를 설정합니다.
export WORK_DIR="/web/socket.io/examples/chat"
3. Project Directory로 이동
[guser@nodejs ~]$ cd socket.io
4. NPM 설치
[guser@nodejs socket.io]$ npm install
/socket.io/package.json에 명시한 dependencies 목록을 설치합니다.
5. Chatt 예제 프로젝트로 이동
[guser@nodejs socket.io]$ cd examples/chat/
6. NPM 설치
/socket.io/examples/chat/package.json에 명시한 dependencies 목록을 설치합니다.
[guser@nodejs chat]$ npm install
7. Socket.IO 코드 리뷰
/socket.io/examples/chat/index.js
var express = require('express'); var app = express(); var server = require('http').createServer(app); var io = require('../..')(server); io.on('connection', (socket) => { socket.on('new message', (data) => { socket.broadcast.emit('new message', data); }); });
Socket.IO를 사용하는 기본적인 서버 사이드 코드입니다.
line 1~4: Express 모듈을 통해 HTTP 서버를 생성하고 Socket.IO 서버와 연결합니다. (line 4의 ‘../..’ 는 ‘socket.io‘ 모듈을 로드합니다.)
line 6: Client의 Connection 이벤트 발생 시, Client Socket 파라미터와 함께 Callback을 받습니다.
line 7: Client로부터 “new message”라는 이벤트 수신할 시, data 파라미터와 함께 Callback을 받습니다.
line 8: “new message”라는 이벤트로 Broadcasting(자신을 제외한 모든 Client에게 전송) 합니다.
/socket.io/examples/chat/public/main.js
var socket = io(); const sendMessage = () => { var message = $inputMessage.val(); message = cleanInput(message); if (message && connected) { $inputMessage.val(''); addChatMessage({ username: username, message: message }); socket.emit('new message', message); } } socket.on('new message', (data) => { addChatMessage(data); });
Socket.IO를 사용하는 기본적인 클라이언트 사이드 코드입니다. View에 관련 된 코드는 다루지 않습니다.
line: 1: Socket.IO 서버에 Connection 요청을 하여 Client socket을 생성합니다.
line: 3: View에서 메세지 전송 시, 호출할 함수
line: 12: Server로 “new message”라는 이벤트를 message 파라미터와 함께 전송합니다.
line: 16: Server로 부터 “new message”라는 이벤트를 수신 시, data 파라미터와 함께 Callback을 받습니다.
8. PM2(프로세스 매니저) 설치
PM2는 Node.js 프로세스 관리도구입니다. PM2를 이용해 애플리케이션 재시작, 재로드뿐 아니라 로그 모니터링도 쉽게 할 수 있습니다.
[guser@nodejs chat]$ npm install pm2 -g
[ PM2 관리 명령어 ]
* app_name 대신 all 또는 애플리케이션 id로 변경하여 사용할 수 있습니다.
9. npm start 스크립트 변경
애플리케이션을 PM2(프로세스 매니저)로 실행하도록 start 스크립트를 변경합니다.
[guser@nodejs chat]$ vi package.json
/socket.io/examples/chat/package.json
[변경 전]
"scripts": { "start": "node index.js" }
[변경 후]
"scripts": { "start": "pm2 start index.js" }
10. 웹 애플리케이션 실행
[guser@nodejs chat]$ npm start
11. 웹 애플리케이션 사이트 접속
가비아 Node.js 호스팅: https://{SSH접속 ID}.gabia.io
로컬: http://localhost:3000/
Redis Publish/Subscribe 기능 활용
1. socket.io-redis 모듈 설치
[guser@nodejs chat]$ npm install socket.io-redis
/socket.io/examples/chat/package.json에 socket.io-redis 모듈을 설치합니다.
2. Redis 연결
/socket.io/examples/chat/index.js
var express = require('express'); var app = express(); var path = require('path'); var server = require('http').createServer(app); var io = require('../..')(server); var redis = require('socket.io-redis'); var port = process.env.PORT || 3000; server.listen(port, () => { console.log('Server listening at port %d', port); }); // Routing app.use(express.static(path.join(__dirname, 'public'))); // Chatroom var numUsers = 0; // Adapting Redis io.adapter(redis({ host: 'localhost', port: 6379 })); io.on('connection', (socket) => { /* … */ });
Socket.IO를 사용하는 기본적인 서버 사이드 코드입니다.
line 6: Socket.IO와 Redis 연결을 위해 redis 객체를 생성합니다.
line 20: Redis의 host와 port 값을 넣어 Socket.IO 서버에 연결합니다.
3. 웹 애플리케이션 실행
[guser@nodejs chat]$ npm start
4. Redis Data Monitoring
사용자의 접속 및 메세지 전송이 Redis를 통해 이루어지는 것을 확인할 수 있습니다.
PM2를 활용한 Clustering 모드 적용
1. Processes config 파일 생성
[guser@nodejs chat]$ vi processes.config.js
/socket.io/examples/chat/processes.config.js
module.exports = { apps : [{ script : "./index.js", instances : "max", exec_mode : "cluster" }] }
[ Instances 옵션 ]
2. npm start 스크립트 변경
[guser@nodejs chat]$ vi package.json
/socket.io/examples/chat/package.json
[변경 전]"scripts": { "start": "pm2 start index.js" }[변경 후]
"scripts": { "start": "pm2 start processes.config.js" }
3. 소켓 연결 설정
/socket.io/examples/chat/public/main.js
var socket = io(url, {transports: [ 'websocket' ]});
line 1: 접속 URL(도메인 혹은 IP)과 transports를 설정 합니다. transports를 websocket으로 설정하면 polling 방식을 사용하지 않게 됩니다.
4. 웹 애플리케이션 실행
[guser@nodejs chat]$ npm start
instances를 max로 설정하여 16개의 프로세스가 실행된 것을 확인할 수 있습니다.
지금까지 Socket.IO와 Redis Pub/Sub을 활용한 채팅 애플리케이션을 만들어 보았습니다. 완성된 프로젝트 코드는 여기에서 확인 할 수 있습니다.
채팅 서버 개발, 가비아 Node.js 호스팅을 이용하면 더 간편해 집니다.
CBT, OBT를 거쳐 안정성이 검증된 컨테이너 기반 Node.js 호스팅을 이용해 보세요!
초보 개발자도 쉽게 사용할 수 있도록 Node.js에 최적화된 호스팅 환경을 제공합니다.
[참고]https://socket.io/
https://github.com/gabia/socket.io