항해 99 5기 TIL_54
▶ Today I Learned
<알고리즘>
[약수]
소요시간: 20분
해결여부: 해결
백준 1037번
https://www.acmicpc.net/problem/1037
const fs = require('fs');
const input = fs.readFileSync("./dev/stdin").toString().trim().split("\n");
let arr = input[1].trim().split(' ')
for (let i = 0; i < arr.length ; i++) {
arr[i] = arr[i]/1
}
if (arr.length === 1) {
n = arr[0]**2 // 약수가 소수만 있는 경우
} else {
let min = Math.min(...arr)
let max = Math.max(...arr)
n = min*max
}
console.log(n)
다른 분들의 풀이를 봐도 비슷했다.
아 그리고 지금와서 생각해보니 소수인 경우 자기 자신을 두 번 곱하는 식도 사실 필요가 없다.
어차피 배열 내에 자기 뿐이라면 최솟값이나 최댓값 둘 다 자기 자신일 테니 바로
max와 min만 곱하면 되는 것이다...!
<실전 프로젝트>
[socket.io]
morgan
npm에서 로깅을 해주는 미들웨어다.
즉, 로그를 남겨주는 것이다.
괄호 안에 무엇을 넣느냐에 따라 출력되는 정보가 조금 달라진다.
우리의 프로젝트에서는 다음의 모드를 사용하였다.
app.use(morgan("dev"));
공식문서에 따르면 다음과 같다.
dev
Concise output colored by response status for development use. The :status token will be colored green for success codes, red for server error codes, yellow for client error codes, cyan for redirection codes, and uncolored for information codes.
이처럼 출력되는 정보에 따라 색깔을 다르게 입혀서 보여준다.
참고자료
https://www.npmjs.com/package/morgan
https://penguingoon.tistory.com/204
app.use(helmet({ contentSecurityPolicy: false })); // 클라이언트 - 서버 간 중요한 정보에 대한 보안을 위해 서버에서 다양한 http header를 자동으로 설정
공식 문서에 따르면 이 작은 구문 하나가 포함하고 있는 미들웨어는 15가지 정도이다.
app.use(helmet.contentSecurityPolicy());
app.use(helmet.crossOriginEmbedderPolicy());
app.use(helmet.crossOriginOpenerPolicy());
app.use(helmet.crossOriginResourcePolicy());
app.use(helmet.dnsPrefetchControl());
app.use(helmet.expectCt());
app.use(helmet.frameguard());
app.use(helmet.hidePoweredBy());
app.use(helmet.hsts());
app.use(helmet.ieNoOpen());
app.use(helmet.noSniff());
app.use(helmet.originAgentCluster());
app.use(helmet.permittedCrossDomainPolicies());
app.use(helmet.referrerPolicy());
app.use(helmet.xssFilter());
이것이 silver bullet은 아니지만 그래도 어느 정도 보안에 도움이 된다고 공식 문서에도 나와있다.
각각에 대한 자세한 설명은 공식문서를 참조해보자.
참고자료:
https://www.npmjs.com/package/helmet
현재까지 짜놓은 socket.io 코드
const app = require("./app");
const server = require("http").createServer(app);
const io = require("socket.io")(server, {
cors: {
origin: "*",
},
});
function publicRooms() {
const {
sockets: {
adapter: { sids, rooms },
},
} = io;
const publicRooms = [];
rooms.forEach((_, key) => {
if (sids.get(key) === undefined) {
publicRooms.push(key); // 해당하는 키의 값이 없다면 새로운 방 생성
console.log('sids',sids)
console.log('key',key)
}
});
return publicRooms;
}
function countRoom(roomName) {
return io.sockets.adapter.rooms.get(roomName)?.size; // 예를 들어 룸 이름을 12로 지정하면 12(1)로 나옴, 1은 한 명 있다는 뜻 물음표는 해당 룸네임이 있는지 없는지 모르기에 붙이는 표시라고 배움
}
// 하나의 소켓에 연결
io.on("connection", (socket) => {
socket["nickname"] = "Anon";
socket.onAny((event) => { // 이벤트가 발생하면 실행될 리스너 추가
console.log(`Socket Event: ${event}`);
});
socket.on("enter_room", (roomName, done) => { // 함수 실행 명령은 서버에서, 실행되는 건 프론트엔드
socket.join(roomName);
done();
socket
.to(roomName) // 나를 제외한 사람들에게 이벤트 실행
.emit("welcome", socket.nickname, countRoom(roomName));
io.sockets.emit("room_change", publicRooms());
});
socket.on("disconnecting", () => {
socket.rooms.forEach((room) =>
socket.to(room).emit("bye", socket.nickname, countRoom(room) - 1)
);
});
socket.on("disconnect", () => {
io.sockets.emit("room_change", publicRooms()); // 연결 끊는데 왜 publicRooms 실행?
});
socket.on("new_message", (msg, room, done) => {
socket.to(room).emit("new_message", `${socket.nickname}: ${msg}`);
done();
});
socket.on("nickname", (nickname) => (socket["nickname"] = nickname));
});
module.exports = { server };
이렇게 배운 내용들과 몇 가지 소스들을 참고해서 코드를 써넣어 두었다.
아직 각각의 요소를 완전히 이해한 것은 아니지만 그래도 하나씩 주석을 달아가며 분석해보았다.
덕분에 지금은 코드를 보았을 때 어떤 기능인지 더욱 잘 알게 되었다.
내일 app.js와 server.js를 같이 정리해보아야 겠다.
▶ 느낀 점
오늘 공부한 시간은 10시간 30분 정도, 항해 수강생들에게 많은 시간은 아니지만 그래도 나름 공부를 한 것 같다.
알고리즘도 풀었고 실시간 채팅 기능을 socket.io를 이용해 구현하기 위해 코드의 틀을 잡으면서 관련 지식들도 구글링했다.
하나하나 배워나가는 재미가 쏠쏠하다.
여전히 모르는 것은 많지만 분명한 것은 어제보다 나은 오늘이었다는 것이다.
어서 자고 내일도 팀원분과 협업하여 코드의 틀을 멋지게 한 번 짜보아야 겠다.
오늘 하루도 고생 많았다, 내 자신 ;)
▶ 공부 시 참고 링크들
https://developer.mozilla.org/en-US/docs/Web/API/Node/appendChild
Node.appendChild() - Web APIs | MDN
The appendChild() method of the Node interface adds a node to the end of the list of children of a specified parent node. If the given child is a reference to an existing node in the document, appendChild() moves it from its current position to the new pos
developer.mozilla.org
https://close-up.tistory.com/entry/Nodejs-HTTP-%EB%AA%A8%EB%93%88
Node.js HTTP 모듈 (1: createServer)
Node.js 비동기 이벤트 기반 JavaScript 런타임 인 Node.js는 확장 가능한 네트워크 애플리케이션을 빌드하도록 설계되었습니다. HTTP는 TCP/IP를 기반으로 하는 프로토콜입니다. Node.js에는 HTTP라는
close-up.tistory.com
https://socket.io/docs/v3/rooms/
Rooms | Socket.IO
A room is an arbitrary channel that sockets can join and leave. It can be used to broadcast events to a subset of clients:
socket.io
https://socket.io/docs/v3/listening-to-events/
Listening to events | Socket.IO
There are several ways to handle events that are transmitted between the server and the client.
socket.io
https://www.zerocho.com/category/NodeJS/post/57edfcf481d46f0015d3f0cd
(NodeJS) Socket.io Server API - 설정하기, 전체 채팅, 1대1 채팅, 그룹 채팅
안녕하세요. 이번 시간에는 Socket.io Server API에 대해 알아보겠습니다. 지난 시간에는 간단하게 한 사용자로부터 받은 데이터를 전체 사용자들에게 뿌려줬는데요. 이번 시간에는 그 데이터를 특정
www.zerocho.com
https://www.npmjs.com/package/hpp
hpp
Express middleware to protect against HTTP Parameter Pollution attacks. Latest version: 0.2.3, last published: 2 years ago. Start using hpp in your project by running `npm i hpp`. There are 125 other projects in the npm registry using hpp.
www.npmjs.com
JWT는 어디에 저장해야할까? - localStorage vs cookie
이번에 지하철 미션을 만들면서 JWT를 클래스 property에 저장했었는데 리뷰어 분께 해당 부분을 피드백 받으면서 어디에 JWT를 저장하는 것이 좋을까 에 대해 고민해보게 되었다. 0. 기본 지식 JWT Js
velog.io
https://www.daleseo.com/js-node-path/
Node.js의 path 모듈로 경로 다루기
Engineering Blog by Dale Seo
www.daleseo.com