#1. HTTP Server
1. Server (통신)
- 통신이란 서로 다른 프로그램간의 데이터 교환을 말한다.
- A라는 프로그램이 B라는 프로그램에게 어떤 데이터를 요청하면 B가 그에 대한 결과를 응답한다.
- 이 때 A를 클라이언트, B를 서버라고 한다.
1) 웹 환경에서의 통신
- 웹 브라우저가(클라이언트) 웹 사이트에 구동되고 있는 웹 서버(서버)에게 URL 형식으로 특정 파일의 내용을 요청한다.
- 웹 서버는 자신이 요청받은 페이지의 HTML 코드를 응답 데이터로 전송한다.
2) 프론트엔드
- 클라이언트 안에서 구동되는 프로그램
- 엔드유저(최종사용자)에게 직접적으로 눈으로 보고, 조작할 수 있는 환경을 제공한다.
- 웹 페이지 형식: HTML + CSS + JS
- 안드로이드(JAVA, 코틀린), IOS(Swift)
3) 백엔드
- 서버 안에서 구동되는 프로그램 혹은 서버 그 자체
2. Node.js로 서버 프로그램 구현하기
Node.js의 http 객체에 포함되어 있는 createServer( ) 함수를 호출하면 서버 객체가 리턴된다.
이 객체에 URL을 식별할 수 있는 처리를 추가하여 특정 URL을 통해 접근하는 클라이언트에게 전달할 데이터를 구성할 수 있다.
html
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<h1>일반링크</h1>
<a href="http://localhost:3217">페이지 이동을 통한 직접 백엔드 접속</a>
<hr />
<h1>Ajax</h1>
<button id="get" type="button">get</button>
<button id="post" type="button">post</button>
<button id="put" type="button">put</button>
<button id="delete" type="button">delete</button>
<h1 id="console"></h1>
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
<script>
document.getElementById('get').addEventListener('click', e => {
e.preventDefault();
(async () => {
try {
const response = await axios.get('http://localhost:3217/');
document.getElementById('console').innerHTML = response.data.message;
} catch(err) {
const errorMsg = `[${err.response.status}] ${err.response.statusText}`;
alert(errorMsg);
return;
}
})();
});
document.getElementById('post').addEventListener('click', e => {
e.preventDefault();
(async () => {
try {
const response = await axios.post('http://localhost:3217/');
document.getElementById('console').innerHTML = response.data.message;
} catch(err) {
const errorMsg = `[${err.response.status}] ${err.response.statusText}`;
alert(errorMsg);
return;
}
})();
});
document.getElementById('put').addEventListener('click', e => {
e.preventDefault();
(async () => {
try {
const response = await axios.put('http://localhost:3217/');
document.getElementById('console').innerHTML = response.data.message;
} catch(err) {
const errorMsg = `[${err.response.status}] ${err.response.statusText}`;
alert(errorMsg);
return;
}
})();
});
document.getElementById('delete').addEventListener('click', e => {
e.preventDefault();
(async () => {
try {
const response = await axios.delete('http://localhost:3217/');
document.getElementById('console').innerHTML = response.data.message;
} catch(err) {
const errorMsg = `[${err.response.status}] ${err.response.statusText}`;
alert(errorMsg);
return;
}
})();
});
</script>
</body>
</html>
Node.js
// 모듈참조
import logger from '../helper/logHelper.js';
import { myIp } from '../helper/UtilHelper.js';
import http from 'http';
import fs from 'fs';
import path from 'path';
const __dirname = path.resolve();
/** 웹 서버 구동 */
const port = 3217; // 포트번호 설정
const ip = myIp();
const server = http.createServer(); // 웹 서버 객체 만들기
/** 포트번호에 대해 리스닝 시작 */
// listen을 시작하면 호출될 콜백함수 지정.
// listen을 시작 -> 백엔드(서버)가 가동을 시작했다는 의미
server.listen(port, () => {
logger.debug(port + '번 포트에서 백엔드가 구동되었습니다.');
logger.debug('- - - - - - - - - - - - - - - - - - -');
// 백엔드에게 접속할 수 있는 주소를 출력
ip.forEach((v,i) => {
logger.debug(`http://${v}:${port}`);
});
});
/** 프론트엔드가 접속했을 때 발생하는 이벤트 */
server.on('connection', (socket) => {
logger.debug(`프론트엔드가 접속했습니다. : ${socket.remoteAddress}, ${socket.remotePort}`);
logger.debug(socket);
});
/** connection 이벤트 발생 직후 프론트엔드에게 결과값을 되돌려 주기 위해 호출되는 이벤트 */
// req(request) -> 요청객체: 브라우저가 서버에게 전달하는 정보를 담고 있다.
// res(response) -> 응답객체: 서버가 브라우저에게 결과를 전송하는 기능을 갖는다.
server.on('request', (req, res) => {
logger.debug(`프론트엔드의 요청 >> [${req.method}] ${req.url}`);
// 프론트엔드가 요청한 URL에 따라 출력 내용을 분기
if(req.url == '/sample.html') {
// 클라이언트에게 전송할 응답 헤더 구성
res.writeHead(200, {
// 브라우저에게 인식시킬 출력 내용의 컨텐츠 형식
'Conent-Type': 'text/html; charset=utf-8'
});
// html 파일을 읽어들여서 응답객체 (res)에 연결
const path = __dirname + '/crud-axios-sample.html';
fs.createReadStream(path).pipe(res);
} else {
// 클라이언트에게 전송할 응답 헤더 구성
res.writeHead(200, {
// 브라우저에게 인식시킬 출력 내용의 컨텐츠 형식
'Content-Type': 'application/json; charset=utf-8',
/** CORS 접근 허용을 위한 설정 */
// 접근을 허용할 도메인 혹은 IP(브라우저에 출력되고 있는 도메인을 의미함, *은 ALL의 의미)
'Access-Control-Allow-Origin': '*',
// 접근을 허용할 전송방식 (기본값은 GET, POST만 허용함)
'Access-Control-Allow-Methods': '*',
});
// 출력할 내용을 저장하기 위한 빈 변수
let json = null;
switch (req.method) {
case 'GET': // 데이터 조회 기능
json = {
rt: 'OK',
message: 'GET방식에 대한 요청입니다.'
}
break;
case 'POST':
json = {
rt: 'OK',
message: 'POST방식에 대한 요청입니다.'
}
break;
case 'PUT': // 데이터 조회 기능
json = {
rt: 'OK',
message: 'PUT방식에 대한 요청입니다.'
}
break;
case 'DELETE':
json = {
rt: 'OK',
message: 'DELETE방식에 대한 요청입니다.'
}
break;
}
// JSON을 문자열로 변환 후 출력
res.write(JSON.stringify(json));
// 클라이언트에 데이터 전송 (통신종료, 출력 종료를 알림)
res.end();
}
});
/** 서버 종료 이벤트 */
// 정상적인 상황에서는 발생할 가능성이 없다.
server.on('close', function() {
logger.debug('백엔드가 종료되었습니다.');
});
'국비수업 > Node.js' 카테고리의 다른 글
[Node.js/express] Cookie / Session (0) | 2022.06.30 |
---|---|
[Node.js] Express (0) | 2022.06.29 |
[Node.js] HTTP Client (0) | 2022.06.27 |
[Node.js] Scheduler (0) | 2022.06.27 |
[Node.js] Log (0) | 2022.06.27 |