클리엘
CLIEL LAB
클리엘
전체 방문자
오늘
어제
  • 분류 전체보기 (514)
    • Mobile (47)
      • Kotlin (47)
    • Web (84)
      • NestJS (9)
      • HTML5 & CSS3 (38)
      • Javascript (20)
      • TypeScript (6)
      • JQuery (11)
    • .NET (301)
      • C# (84)
      • ASP.NET (67)
      • Windows API for .NET (128)
    • Server (53)
      • SQL Server (10)
      • MariaDB (18)
      • Windows Server (6)
      • node.js (19)
    • System (12)
      • 작업LOG (12)
    • Review (11)
    • ETC (6)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

  • 블로그 정리

인기 글

태그

  • .NET
  • asp.net core
  • ASP.NET
  • node.js
  • android
  • HTML5
  • Windows API
  • 변수
  • exception
  • NestJS
  • MariaDB
  • Entity Framework
  • JavaScript
  • jQuery
  • asp.net core web api
  • android studio
  • c#
  • CSS3
  • Kotlin
  • LINQ

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
클리엘

CLIEL LAB

[node.js] WebSocket
Server/node.js

[node.js] WebSocket

2021. 3. 9. 13:41
728x90

웹소켓을 사용하면 웹브라우저를 실행 중인 클라이언트와 실시간으로 데이터를 주고받을 수 있습니다.

 

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() 함수로 서버에 데이터를 보내게 됩니다.

 

서버 발신
서버 수신 후 클라이언트 응답

 

728x90
저작자표시 비영리 변경금지 (새창열림)

'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
    'Server/node.js' 카테고리의 다른 글
    • [node.js] CORS
    • [node.js] socket.io
    • [node.js] express-rate-limit(DOS공격 방어하기)
    • [node.js] JWT 인증
    클리엘
    클리엘
    누구냐 넌?

    티스토리툴바