https://behonestar.tistory.com/33
http://www.incodom.kr/Status_code
https://velopert.com/287
결과 :
수행해야 할 내용 :
서버에서 첫 요청이 들어올 때부터 setTimeout()로 서버 강제 종료 전까지 총 10초동안 요청을 받은 횟수를 카운트 하고, 1초당으로 평균을 구하여 출력한다.
웹 서버 코드 ::
퍼포먼스 측정 요청용 클라이언트 측 코드 ::
html 및 관련 파일 ::
단, client.js 를 통해 요청할 때에는 index.js 파일만 요청하였다.
웹 브라우저로 테스트 하면 index.html의 내용 중에 구성하는데 필요한 js 파일과 css 파일 및 파비콘 파일도 별도로 요청을 하게 된다.
// 서버 측 코드
/**
* index.js, main()
*/
"use strict";
// require()
//const { print, errPrint, parseCookies } = require(`./_system.js`);
//const logger = require('./_logger.js')
const server = require('./web_server.js');
// starting point.
server.start();
/**
* web_server.js
*/
"use strict";
// require()
const { print, errPrint, getFile, parseCookies } = require(`./_system.js`);
const logger = require('./_logger.js')
const serverConfig = require('./properties/server_config.json');
const http = require(`http`);
// constants
const GATEWAY_IP = serverConfig.GATEWAY_IP;
const PORT = serverConfig.PORT;
const HTML_PATH = serverConfig.HTML_HOME_PATH;
const DEFAULT_REQUEST_FILE = serverConfig.DEFAULT_REQUEST_FILE;
// create server.
const server = http.createServer(requestListener);
let flag = true;
let check = true;
let count = 0;
function requestListener(req, res) {
if(flag){
flag = false;
setTimeout(()=>{
check = false;
print(`10초 요청 확인 종료. count : ${count}`);
print(`1초당 요청 처리 횟수 : ${count/10}`);
// 서버 강제 종료
throw new Error('server turn off');
}, 10000);
}
const ip = req.headers['x-forwarded-for'] ||
req.connection.remoteAddress ||
req.socket.remoteAddress ||
req.connection.socket.remoteAddress;
let requestUrl = req.url;
if (requestUrl === '/')
requestUrl = DEFAULT_REQUEST_FILE;
//print(`${ip}에서 '${req.url}' 요청.`);
logger.http(`${ip}에서 '${req.url}' 요청.`);
if (requestUrl === '/favicon.ico') {
getFile(`${HTML_PATH}/favicon32.png`)
.then((data) => {
res.writeHead(200);
res.end(data);
print(`'${req.url}' 요청 '${requestUrl}' 응답 완료.`);
if(check)++count;
}).catch((error) => {
errPrint(error);
throw new Error('File not found.');
});
} else {
getFile(`${HTML_PATH}/${requestUrl}`)
.then((data) => {
let html = data.toString();
res.writeHead(200);
res.end(html);
print(`'${req.url}' 요청 '${requestUrl}' 응답 완료.`);
if(check)++count;
}).catch((error) => {
errPrint(error);
getFile(`${HTML_PATH}/error/page404.html`)
.then((data) => {
res.writeHead(404);
res.end(data);
throw new Error('File not found.');
});
});
}
}
function setCookies(request, response) {
const cookies = parseCookies(request.headers.cookie);
print(`${request.url}, ${cookies}`);
response.writeHead(200, { 'Set-Cookie': 'mc=test' })
}
function start() {
// port open. server start.
server.listen(PORT);
// add event : listening
server.on(`listening`, () => {
print(`PORT : ${PORT} open. 응답 대기 중..`);
});
// add event : error
server.on(`error`, (error) => {
errPrint(`error event : ${error}`);
});
}
module.exports = {
start,
}
/**
* _system.js
*/
"use strict";
const fs = require(`fs`);
const print = text => console.log(text);
const errPrint = text => console.error(text);
if (typeof alert === "undefined") {
//print("alert is undefined.");
//function alert(text) { console.log("alert : ", text) };
var alert = text => print("alert : " + text);
}
const getFile = (filename) => {
return new Promise((resolve, reject) => {
fs.readFile(filename, (error, data) => {
if (error) {
reject(error);
} else {
resolve(data);
}
});
});
}
module.exports = {
print,
errPrint,
alert,
getFile,
}
// ./properties/server_config.json
{
"GATEWAY_IP" : "127.0.0.1",
"PORT" : 8080,
"HTML_HOME_PATH" : "./html",
"DEFAULT_REQUEST_FILE" : "index.html"
}
/**
* _logger.js
*/
const winston = require('winston');
const moment = require('moment');
const winstonRotate = require('winston-daily-rotate-file');
const LOG_PATH = "./log";
/*
const levels = {
error: 0,
warn: 1,
info: 2,
http: 3,
verbose: 4,
debug: 5,
silly: 6
};
/**/
const logger = new winston.createLogger({
transports: [
new winston.transports.Console({
level: 'debug',
format: winston.format.printf(
data => `${moment().format(`YYYY-MM-DD HH:mm:ss.SSS`)} [${data.level.toUpperCase()}] -> ${data.message}`),
}),
new winstonRotate({
level: 'debug',
filename: `${LOG_PATH}/log_`,
maxsize: 100, // byte 단위이나, 제대로 작동 안하는 듯 하다.
maxFiles : 1024,
format: winston.format.printf(
data => `${moment().format(`YYYY-MM-DD HH:mm:ss.SSS`)} [${data.level.toUpperCase()}] -> ${data.message}`),
}),
]
});
module.exports = logger;
// 퍼포먼스 측정용 클라이언트 코드
/**
* client.js
*/
"use strict";
// require()
//const { print, errPrint } = require(`./_system.js`);
const http = require(`http`);
const serverConfig = require('./properties/server_config.json');
// constants
const PORT = serverConfig.PORT;
const options = {
host: 'localhost',
port: PORT,
path: '/',
};
if (true) {
let timer = setInterval(() => {
const req = http.request(options, (res) => {
res.on('data', (data) => {
// print(data);
});
res.on('end', () => {
});
});
req.end();
}, 0.0001);
setTimeout(()=>{clearInterval(timer)}, 10001);
}
// html 파일 및 관련 파일들.
<!--
file name : index.html
<link rel="shortcut icon" href="127.0.0.1:8080/favicon32.png" type="image/x-icon" />
-->
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>node.js web server</title>
<link rel="stylesheet" href="./themes/style.css" type="text/css" media="all" />
<script src="./js/calc.js" type="text/javascript"></script>
</head>
<body>
<p></p>
한글
</body>
</html>
/**
* author : velog.io/@___
* path : ./themes/style.css
*/
@charset "UTF-8";
.calc_table{
position: relative;
background-color: #FFFFFF;
border: 1px solid;
width: 100%;
max-width: 202px;
min-height: 320px;
text-align: center;
table-layout: fixed;
}
.calc_input{
border: none;
text-align: right;
}
td {
border: 1px solid;
}
/**/
body {
/*
background-color: #00FFFF;
/**/
background-image: url("https://media.vlpt.us/images/___/post/8322958b-7949-4b69-b28e-d2c02737e8df/%EB%B3%B4%EB%85%B8%EB%B3%B4%EB%85%B8200.png");
background-repeat: repeat;
}
/**/
.main_container{
position: absolute;
width:100%;
/*
top: 100px;
/**/
}
.calc_area{
position: relative;
height: 100%;
width: 202px;
}
/**
* author : velog.io/@___
* path : ./js/calc.js
*
* .. 내용없음. html 로드 시, js 파일을 요청하는 테스트를 위해 만든 파일.
*/
일단 측정은 하고 멈추려고 서버를 강제로 내렸으나, 별로 좋은 방법으로 보이진 않는다.
근데 머리로 안되겠으면 일단이라도 이렇게 구현은 해야지.