웹소켓을 사용하면 웹브라우저를 실행 중인 클라이언트와 실시간으로 데이터를 주고받을 수 있습니다.
1. 준비
우선 웹소켓을 사용하는 예제를 작성해 보기 전에 node프로젝트를 준비합니다. 아래와 같이 주 진입점인 app.js를 생성하고
const express = require('express');
const app = express();
app.set('port', 80);
app.use((req, res, next) => {
next();
});
const indexRouter = require('./default');
app.use('/', indexRouter);
app.use(function(err, req, res, next) {
console.error(err);
res.send('에러가 발생하였습니다.');
});
app.listen(app.get('port'), function() {
console.log('서버 실행중...');
});
app.js에서 default디렉토리로 라우트를 확장하였으므로 default 디렉터리 안에 클라이언트의 요청에 응답할 수 있는 index.js를 만들어 둡니다.
const express = require('express');
const router = express.Router();
router.get('/', async (req, res) => {
res.sendFile(`${__dirname}/index.html`);
});
module.exports = router;
위 설정에 따라 클라이언트가 / 경로로 요청을 하면 defalut안에 있는 index.js에서 요청을 받게 됩니다. index.js에서는 / 경로의 요청 시 index.html 파일을 응답하도록 하였으므로 같은 위치에 index.html 파일을 추가해 줍니다.
<!DOCTYPE html>
<html>
<head>
<title>test</title>
</head>
<body>
aaa
</body>
</html>
2. ws 사용하기
we의 설치방법은 다음과 같습니다.
npm i ws |
ws를 설치하고 나면 아래와 같이 소켓통신을 처리하는 모듈을 생성합니다. 모듈은 node프로젝트에서 socket디렉토리안에 socket.js라는 이름으로 만들도록 합니다.
const webSocket = require('ws');
module.exports = (server) => {
const wss = new webSocket.Server({ server });
wss.on('connection', (ws, req) => {
const ip = req.headers['x-forwarded-for'] || req.ip;
console.log('client 접속 : ', ip);
ws.on('message', (message) => {
console.log('수신 : ', message);
if (ws.readyState === ws.OPEN) {
ws.send('발신 : server to client');
}
});
ws.on('close', () => {
console.log('clenet 해제 : ', ip);
});
ws.on('error', (error) => {
console.error(error);
});
});
};
최초 클라이언트로 연결이 이루어지면 connection 이벤트로 받아서 접속을 처리합니다. 클라이언트는 해당 이벤트에서 ws객체로 접근할 수 있습니다.
클라이언트로 메세지가 수신되는 건 message이벤트로, 접속이 종료되는 경우는 close이벤트로 받으면 됩니다. close()는 클라이언트에서 웹브라우저를 닫으면 발생합니다. 참고로 클라이언트의 IP는 'req.headers['x-forwarded-for'] || req.ip;'로 알아낼 수 있는데 Express서버를 사용하지 않는 경우라면 req.connection.remoteAddress를 대신 사용합니다.
클라이언트로 메세지를 보내고자 하는 경우 클라이언트 객체의 send로 메시지를 보내면 되는데 경우에 따라 ws.readyState속성으로 현재 연결 상태 여부를 확인할 수 있습니다. 이 모듈은 클라이언트로 메시지를 수신받으면 자동으로 발신 데이터를 응답합니다.
위와 같이 모듈을 생성하고 나면 이제 서버에서 클라이언트의 연결 요청을 받을 수 있도록 소켓을 대기상태에 두어야 합니다. 이를 위해 app.js를 다음과 같이 수정합니다.
const express = require('express');
const websocket = require('./socket/socket');
const app = express();
app.set('port', 80);
app.use((req, res, next) => {
next();
});
const indexRouter = require('./default');
app.use('/', indexRouter);
app.use(function(err, req, res, next) {
console.error(err);
res.send('에러가 발생하였습니다.');
});
const server = app.listen(app.get('port'), function() {
console.log('서버 실행중...');
});
websocket(server);
위에서 만들어둔 socket.js를 통해 websocket객체를 가져와 listen에서 가져온 서버를 전달해 소켓 서버를 연결 대기상태로 만듭니다.
이것으로 연결준비가 끝났습니다. 클라이언트에서 서버에 정상적으로 접속하는지를 확인하기 위해 위에서 만들어둔 index.html을 다음과 같이 수정합니다.
<!DOCTYPE html>
<html>
<head>
<title>test</title>
<script type="text/javascript">
const webSocket = new WebSocket('ws://192.168.137.1:80');
webSocket.onopen = () => {
console.log('연결성공');
};
webSocket.onmessage = (event) => {
console.log('수신 : ', event.data);
webSocket.send('발신 : client to server');
};
</script>
</head>
<body>
<button onClick="javascript: webSocket.send('시작하자!!');" >시작</button>
</body>
</html>
페이지가 로딩되면 WebSocket로 서버와의 소켓 연결을 시도합니다. WebSocket객체는 Internet Express를 제외하고 최신의 웹브라우저는 대부분 지원하고 있습니다. WebSocket의 생성자 매개변수로 we:// 형식을 통해 IP와 포트번호를 지정해 연결할 서버를 알려줍니다. 참고로 예제 서버 IP는 192.168.137.1입니다.
WebSocket에서 서버로의 연결은 onopen으로 할 수 있으며 메세지 수신은 onmessage를 사용합니다. 예제에서는 서버에서 메시지가 수신되면 곧바로 '발신 : client to server'을 내용을 응답하도록 하였습니다. 서버와의 통신 시작은 버튼을 누름으로써 시작되는데 버튼을 '시작'버튼을 누르면 send() 함수로 서버에 데이터를 보내게 됩니다.
'Server > node.js' 카테고리의 다른 글
[node.js] CORS (0) | 2021.03.10 |
---|---|
[node.js] socket.io (0) | 2021.03.09 |
[node.js] express-rate-limit(DOS공격 방어하기) (2) | 2021.03.09 |
[node.js] JWT 인증 (0) | 2021.03.09 |
[node.js] mariaDB CRUD (시퀄라이즈) (0) | 2021.03.08 |