goal
โ GET /messages ์์ฒญ์ 200 ์ํ ์ฝ๋๋ฅผ ์๋ตํด์ผ ํฉ๋๋ค (162ms)
โ GET /messages ์์ฒญ์ ํ์ฑ ๊ฐ๋ฅํ JSON ๋ฌธ์์ด์ ๋๋ ค์ค์ผ ํฉ๋๋ค (37ms)
โ GET /messages ์์ฒญ์ ์๋ต์ ๊ฐ์ฒด์ ํํ์ฌ์ผ ํฉ๋๋ค (34ms)
โ GET /messages ์์ฒญ์ ์๋ต ๊ฐ์ฒด๋results
์ ๋ฐฐ์ด์ ํฌํจํด์ผ ํฉ๋๋ค (21ms)
โ ์ฌ๋ฐ๋ฅธ POST /messages ์์ฒญ์ ์ฒ๋ฆฌํ ์ ์์ด์ผ ํฉ๋๋ค (28ms)
โ GET ์์ฒญ์, ์ต๊ทผ POST ์์ฒญ์ ํตํด ์ ์ถํ ๋ฉ์์ง๊ฐ ๊ฒฐ๊ณผ๋ก ์ ๋ฌ๋์ด์ผ ํฉ๋๋ค (31ms)
โ ์กด์ฌํ์ง ์๋ endpoint๋ฅผ ์์ฒญํ ๋์, 404 ์ํ ์ฝ๋๋ฅผ ์๋ตํด์ผ ํฉ๋๋ค (13ms)
๐๏ธclient - ๐๏ธscript / app.js
ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย - index.html
๐๏ธserver - basic-server.js
ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย - request-handler.js
๋ญ ์๋ฐ ๋๋์ผ๋ก ํ์ผpath ์ ๋ฆฌ
์ด ์ธ ์๋ก ์จ๋ณธ ๊ฒ๋ค๐๏ธ
package.json
์ nodemon
package.json
์์ ๋๋ฒ๊น
์ ์ํด --inspect
์๋ก์ด ๊ฐ๋
๋ค์ ๋ง์ด ์ ํ๊ณ , ํ๋์ฉ ์ฐ์ด๋ณด๋ฉด์ ์ด๋ป๊ฒ ์๊ธด๊ฑด์ง ํ๊ตฌํ๋ค. ์ฌ๋ฐ์๋ค ใ
ใ
์๋ฒ์ ํด๋ผ์ด์ธํธ ์ฐ๊ฒฐํ๋ ๊ฒ ์ญ์ ๋๋ ์ ๊ธฐ ใ
ใ
์๋ ์ฝ๋ ๋ณต๋ถ
ํท๊ฐ๋ฆด ๋๋ง๋ค ๋ค์ ๋ณด๊ธฐ! ๊นํ์๋ ์๋๋ฐ ๋ด๊ฐ ์ ์ ํ๋ ๋ธ๋ก๊ทธ๋๊น ><_
์ ๊ทธ๋ฆฌ๊ณ ๋
ธ๋๋ชฌ ์ฌ์ฉ์ ํฌํธ ์ถฉ๋ ์ด์...
์ด๊ฑฐ๋๋ฌธ์ ๊ณ์ ์๋ฌ๋ฌ๋ค...
$ lsof -nP -iTCP:3000
$ kill -9 (PID๋ฒํธ)
const app = {
// server: 'http://52.78.206.149:3000/messages',
server: 'http://127.0.0.1:3000/messages',
// server: 'http://localhost:3000/messages',
init: () => {
app.addEventHandlers();
app.fetch(json => {
json.results.forEach(app.renderMessage);
});
},
fetchAndRender: () => {
app.fetch(data => {
data.results.forEach(app.renderMessage);
});
},
addEventHandlers: () => {
let submit = document.querySelector('#send .submit');
if (submit) {
submit.addEventListener('submit', app.handleSubmit);
}
},
fetch: callback => {
window
.fetch(app.server)
.then(resp => {
return resp.json();
})
.then(callback);
},
send: (data, callback) => {
window
.fetch(app.server, {
method: 'POST',
body: JSON.stringify(data),
headers: {
'Content-Type': 'application/json'
}
})
.then(resp => {
return resp.json();
})
.then(callback);
},
clearMessages: () => {
document.querySelector('#chats').innerHTML = '';
},
clearForm: () => {
document.querySelector('.inputUser').value = '';
document.querySelector('.inputChat').value = '';
},
renderMessage: ({ username, text, date, roomname }) => {
const tmpl = `<div class="chat">
<div class="username">${username
.replace(/</g, '<')
.replace(/>/g, '>')}</div>
<div>${text
.replace(/</g, '<')
.replace(/>/g, '>')}</div>
<div>${date}</div>
<div>${roomname
.replace(/</g, '<')
.replace(/>/g, '>')}</div>
</div>`;
document.querySelector('#chats').innerHTML =
tmpl + document.querySelector('#chats').innerHTML;
},
handleSubmit: e => {
e.preventDefault();
app.clearMessages();
app.send(
{
username: document.querySelector('.inputUser').value,
text: document.querySelector('.inputChat').value,
roomname: '์ฝ๋์คํ
์ด์ธ '
},
() => {
app.fetchAndRender();
app.clearForm();
}
);
}
};
app.init();
const http = require("http");
const requestHandler = require("./request-handler");
const port = 3000;
const ip = "127.0.0.1";
// const ip = "localhost";
const server = http.createServer(requestHandler);
server.listen(port, ip);
module.exports = server;
//todo
//todo 3. GET /messages ์์ฒญ์ ์๋ต์ ๊ฐ์ฒด์ ํํ์ฌ์ผ ํฉ๋๋ค (4ms)
//todo 4. GET /messages ์์ฒญ์ ์๋ต ๊ฐ์ฒด๋ `results`์ ๋ฐฐ์ด์ ํฌํจํด์ผ ํฉ๋๋ค (2ms)
//! ๊ฒฐ๊ณผ๊ฐ = { results : [ {}, {}, {}....] }
const print = { results : [] }
const requestHandler = function (request, response) {
// ๊ธฐ๋ณธ CORS ์ค์ ์ด ๋์ด์๋ ์ฝ๋ ์
๋๋ค. ์๋์ ์์ต๋๋ค.
const headers = defaultCorsHeaders;
headers["Content-Type"] = "text/plain";
if (request.method === "OPTIONS") {
response.writeHead(200, headers)
response.end()
}
// โญ๏ธ์ฒซ๋ฒ์งธ ๋ฐฉ๋ฒโญ๏ธ
if (request.method === "POST") {
if (request.url === "/messages") {
let body = []
request.on("data", (chunk) => {
console.log(chunk)
//! chunk = <Buffer 7b 22 75 73 65 72 6e 61 6d 65 22 3a 22 4a 6f 6e 6f 22 2c 22 74 65 78 74 22 3a 22 44 6f 20 6d 79 20 62 69 64 64 69 6e 67 21 22 7d>
console.log(body)
//! body = []
body.push(chunk)
}).on("end", () => {
body = Buffer.concat(body).toString()
console.log(body)
//! body = <Buffer>
console.log(Buffer)
//! Buffer = { [Function: Buffer]
//! poolSize: 8192,
//! from: [Function: from],
//! of: [Function: of],
//! alloc: [Function: alloc],
//! allocUnsafe: [Function: allocUnsafe],
//! allocUnsafeSlow: [Function: allocUnsafeSlow],
//! isBuffer: [Function: isBuffer],
//! compare: [Function: compare],
//! isEncoding: [Function: isEncoding],
//! concat: [Function: concat],
//! byteLength: [Function: byteLength],
//! [Symbol(kIsEncodingSymbol)]: [Function: isEncoding] }
console.log(body)
//! body = {"username":"Jono","text":"Do my bidding!"}
body = JSON.parse(body)
console.log(body)
//! body = { username: 'Jono', text: 'Do my bidding!' }
print.results.push(body) // ๋ง๋ ๊ทธ๋ฆ์ ๋ฃ์ด์ฃผ๊ธฐ
response.writeHead(201, headers)
response.end(JSON.stringify(print))
})
} else {
response.writeHead(404, headers)
response.end()
}
// โญ๏ธ๋๋ฒ์งธ ๋ฐฉ๋ฒโญ๏ธ
if (request.method === "POST") {
if (request.url === "/messages") {
let body = "";
request.on('data', (chunk) => {
body = body + chunk
console.log(body)
//! body = {"username":"Jono","text":"Do my bidding!"} ๐๏ธ ๋ ๊ฒ์ body
print.results.push(JSON.parse(body)) // ์๋ฐ์คํฌ๋ฆฝํธ๋ก
console.log(body)
//! body = {"username":"Jono","text":"Do my bidding!"} ๐๏ธ parse๋ body / ์คํธ๋ง์ผ๋ก ํด์๊ทธ๋ฐ์ง ๋ค๋ฅธ์ ์ด ์๋ค?
console.log(print.results)
//! print.results // print = { results : [{username: 'Jono', text: 'Do my bidding!'}] } ๐๏ธ ๋ฌธ์ ์์ด ์ ๋ค์ด๊ฐ ใ
ใ
๊ทผ๋ฐ parseํด์ฃผ์ง ์์ผ๋ฉด ์ญ์ฌ๋์ฌ ๋ฌธ์ ๊ฐ ์๊ธธ๊ฑธ?
}).on('end', () => {
console.log(print)
//! print = { results: [{username: 'Jono', text: 'Do my bidding!'}] } => โญ๏ธstringify๋ ๋ง์ง๋ง ๊ฒฐ๊ณผ๊ฐโญ๏ธ
response.writeHead(201, headers)
response.end(JSON.stringify(print)) // JSON์ผ๋ก
})
} else {
response.writeHead(404, headers)
response.end()
}
} else if (request.method === "GET") {
if (request.url === "/messages") {
response.writeHead(200, headers)
response.end(JSON.stringify(print))
// response.end(print)
console.log(print)
//! TypeError [ERR_INVALID_ARG_TYPE]: The "chunk" argument must be one of type string or Buffer. Received type object
} else {
response.statusCode=404
response.end()
}
}
};
const defaultCorsHeaders = {
"access-control-allow-origin": "*",
"access-control-allow-methods": "GET, POST, PUT, DELETE, OPTIONS",
"access-control-allow-headers": "content-type, accept",
"access-control-max-age": 10 // Seconds.
};
module.exports = requestHandler;