HTTP 연결방식(단방향 연결)
Client에서 어떤 url로 request 보내게 되면 server는 그 request에 해당하는 로직을 수행하게 된다. 그 로직을 수행하게 되면 결과값으로 response를 client에게 보내게 된다. 요청을 주면 응답을 보내고 응답을 보내는 순간 연결이 끊기게 된다. 이것이 단방향 연결 방식이다.
client가 반드시 server로 요청을 해야지 server는 응답를 보낼 수 있다.
한번 요청하고 응답했었을 때 다음에도 동일한 클라이언트가 요청을 해도 동일한 클라이언트인지 인식을 못한다.(왜냐면 단방향이기 때문) 그래서 jwt 인증방식 이런것들을 사용하는것이다.양방향 연결이 필요한 경우?
실시간 경매나 실시간 채팅 같은 경우는 실시간으로 브라우저에 보여야한다.http
polling방식
- 단방향 연결인데 계속 클라이언트가 n초마다 요청을 보내서 양방향 연결 방식으로 보이는것이다.
- 모든 브라우저가 n초 마다 서버에 요청을 보내면 서버가 부하가 된다.
이런문제로 인해 Socket 연결방식(양방향)이 나오게 되었다.
* Soket : 입구, 콘센트 Socket
nestJS-websockets-geteways 공식문서
socket 프로그래밍은 geteway를 사용해서 개발한다.
설치
npm i --save @nestjs/websockets @nestjs/platform-socket.io
npm install socket.io
nest g ga chats // geteway 만들기
nest g mo chats // module 만들기
chats.Module.ts
import { Module } from '@nestjs/common';
import { ChatsGateway } from './chats.gateway';
@Module({
providers: [ChatsGateway], << 등록하기
})
export class ChatsModule {}
index.hbs
<html>
<head>
<meta charset='utf-8' />
<title>{{data.title}}</title>
<link href='css/styles.css' rel='stylesheet' />
</head>
<body>
<div id='hello_stranger'></div>
<div id='chatting_box'></div>
<form id='chat_form'>
<input placeholder='Chat..' />
<button type='submit'>Chat</button>
</form>
// 소켓을 사용하기 위해 소켓io라는 cdn 서비스가 필요하다. 그 라이브러리는 링크로 스크립트로 껴넣을 수 있다. 아래같이 사용한다.
<script src='https://unpkg.com/@babel/standalone/babel.min.js'></script>
// babel: 최신 JS 문법은 브라우저에서 사용할 수 있도록 해주는것
<script
src='https://polyfill.io/v3/polyfill.min.js? features=default%2Ces2015%2Ces2016%2Ces2017%2Ces2018%2Ces2019'></script>
// polyfill 은 promist.all 같은것 도 할수 있게 해주는것
<script
src='https://cdn.socket.io/3.1.3/socket.io.min.js'
// socket.io를 클라이언트에서 사용할 수 있도록 해준다.
integrity='sha384-cPwlPLvBTa3sKAgddT6krw0cJat7egBga3DJepJyrLl4Q9/5WLra3rrnMcyTyOnh'
crossorigin='anonymous'></script>
<script src='js/script.js'></script>
</body>
</html>
script.js
const socket = io('/');
// ('/') : 네임스페이스
// io 가 socket.io.min.js 여기에 있는 하나의 요소(메소드)이다.
const getElementById = (id) => document.getElementById(id) || null;
// document.getElementById(id) 해당 id를 통해서 dom요소를 잡아오는 것이다.
//* get DOM element
const helloStrangerElement = getElementById('hello_stranger');
const chattingBoxElement = getElementById('chatting_box');
const formElement = getElementById('chat_form');
function helloUser() {
const username = prompt('What is your name?');
// (1) socket.emit('new_user', username)
console.log(username)
// socket.emit() 클라이언트에서 서버로 보낼때 / 서버에서 클라이언트로 보낼 때 사용한다.
// 첫번째 인자: 이벤트 이름, 두번쩨 인자 : 데이터
// 이렇게 보내면 서버에서는 받아서 처리를해줄 수 있다.
socket.emit('new_user', (data)=> {console.log(data)})
socket.on('hello_user', (data)=> { console.log(data)})
// 데이터를 받을 때 callback 함수로 받을 수 있다. 데이터를 받자 마자 콜백함수가 실행된다.
}
function init() {
helloUser();
}
init();
// init()이 실행되어 helloUser가 실행되는데 console.log(username)을 하게되면
// 해당 name이 console창에 뜨게 된다. (웹브라으저에서 입력을 하면 받아오는것이다.)

chats.gateway.ts
import {
ConnectedSocket,
MessageBody,
SubscribeMessage,
WebSocketGateway,
} from '@nestjs/websockets';
import { Socket } from 'socket.io';
@WebSocketGateway()
export class ChatsGateway {
@SubscribeMessage('new_user') // 여기서 이벤트를 쓰게 되면 해당 함수를 실행시켜준다.
// handleMessage(client: any, payload: any): string { return 'Hello world!'}
handleNewUser(
@MessageBody() username: string,
@ConnectedSocket() socket: Socket, // socket으로 amit, on이 가능하다.
) : string {
console.log(username)
socket.emit('hello_user', `hello ${username}`) << // 서버에서 클라이언트로 보내기
// 'hello_user' 라는 이벤트로 `hello ${username}` 데이터로 보내기.
return 'hello world'
// socket.emit('new_user', (data)=> {console.log(data)}) 으로 받게 됨.
}
}
// handleMessage 이것은 실행시켜주는 함수이다. controller 라고 생각하면되고 이름은 변경할 수 있다. 인자들을 데코레이터를 가공해서 만들어주고 어떤 데이터를 받을지 타이핑을 해주는것임.
// @SubscribeMessage('new_user') 해서 데코레이터가 on으로 메세지를 받은것이다.

사용자가 입력을 하는 순간 프론트에서 username이 담기게 되고 담긴 username이 socket으로 보내게 된다. 보낼 때는 이벤트 등록을 해야하는데 new_user라는 이벤트로 등록을 했다. 그래서 amit으로 보내게 되면 서버에 socket이 들어오게 되면 해당하는 이벤트를 찾는다.(controller 처럼) 해당 이벤트가 new_user에 대해 handleNewUser(인자로 클라이언트에서 보낸 데이터를 받는다) 받은 username을 console에 찍어준것이다.
새로고침을 하는 순간 Socket은 끊기게 되고 새로운 아이디로 부여 받는다.
socket은 개별적으로 id가 존재한다. 그 id는 연결이 끊기기 전까지 유지가 된다. 서버 자체는 클라이언트에 접속한 id를 통해 해당 유저를 식별할 수 있는 것이다.

정리가 잘 된 글이네요. 도움이 됐습니다.