코드스테이츠/코드스테이츠 @ 팀 프로젝트

[코드 스테이츠 / Final-Project] 138일차, "배움의 어려움.."

Je-chan 2021. 12. 4. 02:25

 

 

일단은 어느정도 공부가 끝났다. 공부를 했을 때 적은 js 파일을 여기 코드 스니펫에 옮겨보도록 하겠다.

// * WSS 강의
// TODO 1. WebSocket 이란?
/**
 * > 이것 덕분에 실시간 채팅, 알림 등을 사용할 수 있다.
 * @ http 란?
 * > http와 websocket 은 같은 프로토콜이다.
 * > http 는 request 를 보내면 서버가 반응을 보내는 방식으로 이뤄져 있다.
 * > 서버는 client 가 누구인지를 잊어버리고, 그렇기 때문에 매번 쿠키를 보낸다. 이 현상을 stateless 라고 한다
 * > 그렇기 때문에 real Time 으로 이뤄지는 작업이 아니다
 * > 서버는 Request 를 기다리고 그 다음에서야 작업을 하지, 서버가 client 에 먼저 뭔가를 요구할 수 없다.
 * > client 를 기억하지 못하기 때문이다.
 *
 * @ websocket 이란?
 * > 브라우저가 서버로 webSocket request 를 보내면 서버가 받거나 거절을 한다
 * > 만약 서버가 이 요청을 받으면 connection 이 이뤄진다. 이를 establish 라고 함
 * > 터널을 만들어 브라우저와 서버가 연결되는 것이고 그렇기에 서버는 클라이언트를 인식한다
 * > 그렇기에 서버가 클라이언트에게 먼저 말을 건낼 수 있게 된다.
 * > 이는 request, response 의 과정이 아니다.
 * > 서버는 반드시 2 개의 메세지를 보내게 된다. bi-directional 연결이기 때문.
 * > 서버는 유저에게 메세지를 보낼 수 있고, 마찬가지로 유저도 서버에게 요청을 보낼 수 있다. establish가 됐기 때문에 가능한 일
 */

// TODO 2. http.createServer 로 서버 하나 더 만드는 이유
/**
 * > websocket 을 사용하기 위해선 node.js 환경에서 프로토콜을 두 개 만들게 된다
 * > http 를 Import 한 후 http 서버를 createServer 하고 그걸 WebSocket 프로토콜 서버로 오버라이딩 한다
 * > 규약이 다르기 때문에 WebSocket 을 위한 것과 우리 http 통신을 위한 것 두 개가 존재해야 한다.
 * > Websocket 통신만을 위한 서버를 만든다면 하나의 서버만을 구축해도 되지만, HTTP 통신까지 같이 쓰는 경우가 많으므로 두 개 만들게 된다
 * > 즉, 한 서버에서 두 개의 통신 규약을 모두 활용할 수 있게 되는 것
 */

// TODO 3. Websocket 에 대한 기본 이해
/**
 * > 웹 소켓에도 event 가 존재한다. JS eventHandle 와 같이 이벤트가 발생하면 콜백 함수를 실행한다
 * > 웹소켓은 listen 하는 이벤트가 특정돼 있다. 그리고 event.target 을 받는 함수와 같은 것이 존재한다
 * > ex)
 * > wss.on("connection")
 * >> On 은 이벤트가 발생하기를 기다리는 메소드다
 * >> connection은 서버와 클라이언트를 이어주는 것을 의미한다
 * > callback 으로 socket 을 받는다고 한다. 소켓은 연결된 어떤 사람이 된다. 연결된 브라우저와의 conact 를 의미하고
 * > 이 소켓을 사용해서 실시간 채팅을 구현할 수 있게 되는 것이다.
 *
 * > 프론트엔드와 백엔드가 연결되기 위한 소스가 필요함
 * > 그게 바로 app.js 의 const socket = new Websocket(`ws://${window.location.host}`)
 * > 브라우저와 서버 사이의 연결을 이런식으로 하게 된다.
 * > 그리고 app.js 에서 만든 socket 이 연결고리가 되어 메시지를 보내는 것.
 * > 용어에 대한 정리를 하면 socket 은 연결을 의미하고, 클라이언트에서의 socket 은 서버와의 연결고리, 서버에서 socket 은 클라이언트와의 연결고리다
 *
 * ? 서버에서 클라이언트에 연락을 준다고 한다면
 * > wss.on('connection', (socket) => {socket.send()} 이런식으로 함.
 * > 이 의미는 클라이언트와 연결이 되면 바로 메세지를 보낸다는 되는
 *
 * > 클라이언트 쪽에서는 socket.addEventListener('open', () => {~~}) 이런 식으로 서버의 요청을 받음.
 * > open 이란 서버와의 연결고리가 열렸다는 것을 의미한다
 * > socket.addEventListener('open', () => {~~})  => message 를 받았을 때 처리
 * > socket.addEventListener('close', () => {~~}) => 서버와의 연결이 끊어졌을 때
 *
 * ? 물론 bi-connection 이기에 백엔드에서도 소식을 들을 수 있다
 * > wss.on('connection', (socket) => socket.on('close', ()=> {~~}) )
 * > 브라우저 탭을 닫는 경우 등
 *
 * > 클라이언트에서 메세지를 보내는 방법도 socket.send('') 로 동일하다
 */

// TODO 4. 누가 보냈는지 기억하기
/**
 * > 서버는 두 개의 브라우저와 연결은 돼 있지만 각자의 브라우저만 연결된 상태
 * > 그러므로 누구와 연결된 것인지를 저장하기 위해서 데이터베이스를 이용하게 된다
 * > 문제가 있다면 닉네임과 채팅 내용은 모두 message 로 가게 된다. 그러나 백엔드에서는 그것을 구별할 방법이 없다는 것
 * > message 는 정말 모든 종류의 내용이 담겨 있음
 * > 그렇기에 구별해주기 위해서는 프론트엔드에서 어떤 양식(type 등)으로 보내주고 그 양식을 분석해서 구별해야 함
 * > 그 방법 중에 하나가 JSON 의 형식으로 보내는 것
 * {
 *   type: 'nickname',
 *   payload: 'message 내용'
 * }
 * > JSON 형태로 보내줄 때의 이점은 클라이언트나 서버가 자바스크립트라는 것을 보장하지 않기에 특정 언어의 형식이 아닌 JSON 의 형식으로 만들어주는 것은 매우 좋은 것
 * > Websocket 은 자바 스크립트에 국한되어 있는 것이 아니라 브라우저 API 이기 때문에 자바 스크립트의 문법인 object 의 형식으로 보내서는 안 되는 것. 그 서버가 자바스크립트의 object 를 이해할 수 있을지는 모르기 때문
 * > 문제는 message 는 반드시 String 타입으로만 받는다. 그래서 JSON.stringify, JSON.parse 가 답.
 * > 그게 app.js 에서 사용하는 function makeMessage
 *
 *
 */
// TODO 1. Socket IO란?
/**
 * > 실시간, 양방향, 이벤트 기반의 통신을 가능하게 한다
 * > 브라우저와 백엔드 양방향을 의미
 * > Socket.io 는 websocket 을 실행하는 것이 아님.
 * > Socket.io 가 실시간, 양방향, 이벤트 기반 통신을 제공하는 방법 중의 하나로 Websocket 을 사용하는 것
 * > 브라우저가 websocket 을 지원하지 않을 때, 핸드폰이 websocket 을 지원하지 않을 때에도 작동하도록 함
 * > 가끔 websocket 을 사용하는 것일 뿐
 * > 만약 socket.io 가 브라우저에서 웹소켓을 지원한다는 것을 알면 그것을 사용
 * > 없다면 HTTP long-poling 등을 사용한다.
 * > 와이파이가 잠깐 끊겨도 다시 자동적으로 연결해주는 기능도 존재함
 * > Websocket 에 비해 탄력성이 좋고, 더욱 편리한 것
 */

// TODO 2. Socket.io 사용
/**
 * > npm i socket.io
 * > import SocketIo from 'socket.io'
 * > 이후 io 서버를 만들어줘야 함
 *
 * > const server = http.createServer(app)
 * > const io = SocketIo(server)
 *
 * ? Socket.io 의 다른 점
 * * 1.  특정한 Event를 emit 해줄 수 있다. 어떤 이름이든 상관 없음.
 * > 그 이름에만 맞춰서 socket.on('이름',)으로 들어주면 됨.
 * >> 즉, message 라는 이벤트에 국한되지 않다는 것
 *
 * * 2. 자바스크립트 object 를 전송해줄 수 있다. string 만 전송할 필요는 없는 것.
 * > 알아서 String 으로 바꾸고 또 알아서 객체로 바꿔준다
 *
 * * 3. 서버에서 callback function 을 받는다.
 * > socket.emit 의 세 번째 인자로 callback function 을 받는다
 * > 즉 , socket.emit 에서 (프론트엔드) 들어갈 수 있는 건
 * > 첫 번째, 이벤트의 이름
 * > 두 번째, payload 로 들어갈 값들 (여러 개 가 들어갈 수 있음. 원하는 만큼)
 * > 세 번째, 서버에서 실행될 함수 (항상 마지막 인자가 돼야 한다)
 *
 * > 그러나 세 번째의 함수가 서버에서 실행되는 함수가 절대 아님. 그렇지 않으면 클라이언트에서 서버를 조작할 수 있게 됨
 * > 프론트엔드에서 실행되는 함수임.
 * > 그러나 그 실행된 함수를 실행시키는 작업을 서버에서 해주는 것
 *
 * > 소켓 그룹이 필요함. room. 소켓으로 서로 실시간으로 소통할 수 있는 공간을 의미함
 * > socket.io 는 Room 을 기본적으로 제공하고 socket.join(room 이름) 이러면 그 룸에 참여하게 되는 것
 *
 */

// TODO 3. 여러 method들
/**
 * * 1. disconnectiong: 고객이 접속을 중단하지만 완전히 방을 나가지 않았을 때
 * > 창을 닫거나, 컴퓨터를 완전히 꺼졌을 때, 방에 message 를 보낼 수 있는 것
 *
 * * 2. Adapter
 * > 다른 서버 사이에 실시간 어플리케이션을 동기화하는 과정
 * > 서버의 메모리에서 Adapter 를 사용하고 데이터베이스에는 아무것도 저장하고 있지 않음
 * > 서버를 종료하고 다시 시작한다면 모든 room 과 message, socket 이 사라져서 0이 되는 것
 * > 그리고 서버는 반드시 열려 있어야 한다.
 */