전통적인 브라우저 렌더링 방식인 완전한 HTML파일을 서버로부터 제공받는 방법의 한계를 해결하는 Socket.io는 웹 페이지에서 사용자와의 활발한 상호작용을 간편하게 제공한다. socket.io를 사용하면 실시간 채팅 기능과 서버와 클라이언트단의 활발한 통신이 필요한 기능들을 간단하게 구현할 수 있다. 따라서 실시간 채팅을 구현하고자 하는 프로젝트에서 매우 유용하게 사용할 수 있다.
자바스크립트를 사용하여 브라우저 종류와 상관없이 실시간 웹을 구현할 수 있도록 한 기술이다.
socket.io 는 ECMA Script 표준 기술이 아니고, Guillermo Rauch가 만든 Node.js 모듈로서 LearnBost 회사의 저작물로, MIT 라이센스를 가진 오픈소스이다.
package.json
파일을 하나 생성하여 아래 내용을 저장한다.{
"name": "socket-chat-example",
"version": "0.0.1",
"description": "my first socket.io app",
"dependencies": {}
}
express
프레임 워크를 사용하여 HTTP 통신 요청과 핸들러를 생성할 것이다.npm install express@4
const express = require('express');
const app = express();
const http = require('http');
const server = http.createServer(app);
// HTTP 서버에 제공할 수 있는 함수 핸들러로 초기화 된다.
app.get('/', (req, res) => {
res.send('<h1>Hello world</h1>');
});
// 클라이언트가 루트 경로로 접속한 경우를 처리한다
server.listen(3000, () => {
console.log('listening on *:3000');
});
// HTTP 서버가 포트 3000에서 수신한다. 클라이언트가 3000번으로 접근하면 처리할 수 있다.
위를 아래와 같이 실행하면 서버의 터미널에 다음과 같이 출력된다.
node server.js
npm install socket.io
io.on
server.js
에 다음과 같이 추가한다.const express = require('express');
const app = express();
const http = require('http');
const server = http.createServer(app);
const { Server } = require("socket.io");
const io = new Server(server);
app.get('/', (req, res) => {
res.sendFile(__dirname + '/index.html');
});
io.on('connection', (socket) => {
console.log('a user connected');
});
server.listen(3000, () => {
console.log('listening on *:3000');
});
io
socket.io
에서 제공하는 Server
생성자 함수를 사용하여 생성된 인스턴스(io
)를 사용하여 socket에서 제공하는 여러 메서드들을 사용할 수 있다. io
는 클라이언트 단에서 발생할 이벤트에 이벤트 핸들러를 등록할 수 있게 한다.
io.on
메서드의 첫번째 인수인 'connection'은 클라이언트가 소켓에 연결한 경우 발생하는 이벤트이다.
io.on("connection", (socket) => {
// ...
});
socket.on
서버에서 socket.on
은 클라이언트단에서 발생한 이벤트를 선택적으로 캐치하여 이벤트 핸들러를 등록한다. 이때 클라이언트에서 발생하는 이벤트는 클라이언트단에서 개발자가 임의로 설정할 수 있다. 이벤트는 문자열로 지정하며 직접 이벤트를 발생시킬 수 있다. 그에 대한 예제는 바로 다음인 5번 socket.emit
을 참고하자.
// server
socket.on("news", (data) => {
console.log(data);
});
// with several arguments
socket.on("news", (arg1, arg2, arg3) => {
// ...
});
// or with acknowledgement
socket.on("news", (data, callback) => {
callback(0);
});
아래 예제는 서버의 소켓에 어떤 클라이언트가 접속 했을 때 클라이언트가 'chat message'이벤트를 발생시킨 경우 호출할 이벤트 핸들러를 등록할 수 있다.
// server
io.on('connection', (socket) => {
socket.on('chat message', (msg) => {
console.log('message: ' + msg);
});
});
socket.emit
클라이언트는 자체적으로 이벤트를 발생시킬 수 있는데, 다음 예제는 form에서 submit 이벤트가 발생한 경우, 소켓에서 'chat message' 이벤트를 발생시키는 예제이다. 그에 대한 서버측의 처리는 위의 예제처럼 해결할 수 있다.
<script src="/socket.io/socket.io.js"></script>
<script>
// client
var socket = io();
var form = document.getElementById('form');
var input = document.getElementById('input');
form.addEventListener('submit', function(e) {
e.preventDefault();
if (input.value) {
socket.emit('chat message', input.value);
// 소켓에게 'chat mssage' 이벤트 발생
input.value = '';
}
});
</script>
io.emit
서버는 클라이언트와 마찬가지로 소켓에 접속한 클라이언트들에게 이벤트를 발생시킬 수 있다. 그와 동시에 어떤 값을 전달할 수 있다.
다음은 소켓에 어떤 클라이언트가 접속한 경우, 소켓에서 chat message 이벤트가 발생하면(이는 클라이언트가 발생시켰을 것이다), 다시 클라이언트에게 전달받은 msg를 가지고 'chat message'이벤트를 발생시켜서 msg를 모든 클라이언트들에게 뿌려줄 수 있다.
즉, 어떤 소켓에 연결된 한 클라이언트가 'chat message' 이벤트를 발생시키며 msg를 전달하면, 이를 서버가 받아서 소켓에 연결된 모든 클라이언트에게 뿌려주는 예시이다.
// server
io.on('connection', (socket) => {
socket.on('chat message', (msg) => {
io.emit('chat message', msg);
});
});
더욱 자세한 예시들과 실시간 채팅 구현을 연습해보고 싶다면 다음 사이트를 참고해서 연습하자.
socket.io 실시간 채팅 구현 예제