NameSpace

 

서버와 클라이언트가 연결되면 실시간 데이터 공유가 가능한데, socket을 그냥 사용하면 모든 데이터가 모든 socket으로 들어가게된다.

하지만 특정 페이지에서 소켓이 보내주는 모든 실시간 데이터를 모두 받을 필요가 없다.

그래서 특정 노드끼리만 연결한 것이 namespace이다. 즉 같은 네임스페이스 소켓 끼리만 통신을한다. 

@WebSocketGateway() //게이트웨이 설정
export class ChatGateway{
    @WebSocketServer() server: Server; // 웹소켓 인스턴스 생성
    
    @SubscribeMessage('message') //해당 이벤트 구독
    handleMessage(socket: Socket, data: any): void {
        this.server.emit('message', `client-${socket.id.substring(0,4)} : ${data}`,);
    }
}

게이트웨이 네임스페이스 설정


@WebSocketGateway({namespace: 'chat'}) //게이트웨이 설정
export class ChatGateway{
    @WebSocketServer() server: Server; // 웹소켓 인스턴스 생성
    
    @SubscribeMessage('message') //해당 이벤트 구독
    handleMessage(socket: Socket, data: any): void {
        this.server.emit('message', `client-${socket.id.substring(0,4)} : ${data}`,);
    }
}

 

 

 

'WEB > WebSocket' 카테고리의 다른 글

(WebSocket) NestJS 채팅 어플리케이션 만들기  (0) 2024.05.04
웹소켓  (0) 2024.05.04

채팅을 만들려면 채팅방도 만들어야 하고, 접속한 유저 모두에게 메시지를 발송하는 브로드캐스팅 기능도 필요하고 여러 기능들이 필요하다.

 

socket.io는 웹소켓을 기반으로 서버와 클라이언트의 양방향 통신을 지원하는 라이브러리이다.

 

작업 순서

  1.  프로젝트 생성 및 패키지 설치
  2.  정적 파일 서비스를 위한 main.ts 설정
  3.  socket.io 서버 구동을 위한 게이트웨이 만들기
  4.  클라이언트 측 코드 작성
  5.  테스트

 

1.패키지 설치하기

 

@nestjs/websockets : 클라이언트와 서버를 연결하고 양방향 통신 또는 데이터 전송이 가능하게 해주는 패키지

@nestjs/platform-socket.io  : 웹소켓의 성능향상이나, 실시간 데이터 동기화 같은 웹소켓 프로토콜 기반의 프로그램 작성 시 필수인 패키지

 

2. 정적 파일 서비스 설정

 

NestJS에서는 정적 파일을 불러오는 기능을 제공한다.

 

// 반환형을 NestExpressApplication형으로 지정해 정적 메서드를 사용한다.
const app = await NestFactory.create<NestExpressApplication>(AppModule);
// useStaticAssets : 정적 파일의 경로를 지정
app.useStaticAssets(join(__dirname, '..', 'static'));

 

 

3. 서버 측 작업을 위한 게이트웨이 만들기

 

NestJS에서는 웹소켓을 사용한 통신을 받아주는 클래스를 게이트웨이라한다.

게이트웨이를 만드는 방법은 @WebSocketGateway() 데코레이터를 클래스에 붙이면 된다.

 

@WebSocketServer() : 실제 WebSocket 서버 인스턴스를 참조하게 되서 클라이언트에 메시지 전송, 연결, 관리같은 WebSocket 서버를 제어할 수 있다.

 

@WebSocketGateway() //게이트웨이 설정
export class ChatGateway{
    @WebSocketServer() server: Server; // 웹소켓 인스턴스 생성
    
    @SubscribeMessage('message') //해당 이벤트 구독
    handleMessage(socket: Socket, data: any): void {
        this.server.emit('message', `client-${socket.id.substring(0,4)} : ${data}`,);
    }
}

 

3-1. 게이트웨이를 모듈에 등록하기

 

게이트웨이는 다른 클래스에 주입해서 사용할 수 있는 프로바이더이다.

 

@Module({
  imports: [],
  controllers: [AppController],
  providers: [AppService, ChatGateway], // 게이트웨이를 프로바이더로 등록, 게이트웨이는 다른 클래스에 주입해서 사용할 수 있는 프로버이더이다.
})

 

 

4. 클라이언트를 위한 index.html 수정

 

웹소켓은 브라우저가 표준 프로토콜이라서 자체적으로 지원을해서 따로 라이브러리를 사용할 필요가 없다.

반면 socket.io는 브라우저에서 따로 지원을 안해줘서 설정을 해줘야한다.

 

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <h2>Simple Nest Chat</h2>
    <div id="chat"></div>
    <input type="text" id="message" placeholder="메시지를 입력해주세요.">
    <button onclick="sendMessage()">전송</button>
</body>
<!-- jquery 로드 -->
<script src="https://code.jquery.com/jquery-3.6.1.slim.js">
</script>
<!-- socket.io 인스턴스 생성 -->
<script src="http://localhost:3000/socket.io/socket.io.js"></script>
<script>
    const socket = io('http://localhost:3000');
    // 전송 버튼을 클릭 시 입력된 글을 message 이벤트로 보냄
    function sendMessage(){
        const message = $('#message').val();
        socket.emit('message', message);
    }
    socket.on('connect', () =>{
        console.log('connected');
    });
    socket.on('message', (message) =>{
        $('#chat').append(`<div>${message}</div>`);
    });
</script>
</html>

 

socket.on('이벤트', '받은 데이터') : emit()에서 발생된 이벤트리스너로 데이터를 받는다

socket.emit('이벤트', '넘겨줄 데이터') : 서버에서 해당 이벤트를 발생시켜 클라이언트 쪽의 해당 이벤트 리스너에게 데이터를 넘겨준다.

 

'WEB > WebSocket' 카테고리의 다른 글

NameSpace 설정하기  (0) 2024.05.10
웹소켓  (0) 2024.05.04

 

웹소켓 소개

 

사용자가 직접 화면을 갱신하지 않아도 자동으로 화면을 갱신하는 애플리케이션이 있다.

주식이나 채팅 애플리케이션이 대표적이다. 이러한 일을 하려면 서버에 주기적으로 요청을 보내서 받아오거나 서버에서 데이터를 보내주어야한다.

요청에 대해서만 응답하는 HTTP 통신

 

웹은 HTTP 프로토콜 위에서 동작하고 있기 때문에 요청을 보내야지만 서버가 응답을 주게 된다.

즉 양방향 통신을 지원하지 않는다.

 

웹소켓(WebSocket)

웹소켓(ws)은 하나의 TCP 컨넥션으로 서버와 클라이언트 간에 양방향 통신을 할 수 있게 만든 프로토콜이다.

웹소켓은 양방향 통신을 지원하므로 브라우저 상에서 리프레시 없이 실시간성을 요구하는 애플리케이션을 구현한다.

 

 

양방향 통신이 가능한 웹소켓

 

웹소켓의 특징은 크게 두 가지이다.

 

1. 양방향 통신

양방향 통신은 데이터를 동시에 처리한다는 뜻이며 클라이언트와 서버가 원하는 때 데이터를 주고받을 수 있다는 의미.

통상적인 HTTP 통신은 클라이언트가 요청하는 때만 서버가 응답하는 단방향 통신이였다.

 

2. 실시간 네트워킹을 구현하는 것이 용이하다.

웹 환경에서 연속된 데이터를 빠르게 노출하고 싶을 때, 예를 들어 채팅이나 주식 앱에 적합.

또한 브로드캐스팅을 지원하므로 여러 클라이언트와 빠르게 데이터를 교환할 수 있어 편리하다.

※브로드캐스팅 : 데이터를 전송할 때 여러 단말장치 대해 동일한 정보나 메시지를 일제히 전송하는 기술.

 

 

 

웹소켓의 동작 방법

 

웹소켓 프로토콜은 크게 핸드 쉐이크와 데이터 전송으로 나눌 수 있다.

 

핸드 쉐이크 : 통신을 하는 웹서버와 브라우저가 암호화 통신을 시작할 수 있도록 신분을 확인하고, 필요한 정보를 클라이언트와 서버가 주고 받거니하는 과정이 악수와 비슷해서 붙혀진 이름이다.

 

SSL 핸드쉐이크 과정

 

 

※ SSL : TCP/UDP같은 일반적인 통신에 안전한 계층을 추가하는 방식

SSL에 탑재된 기술 : 통신 대상을 확인하는 신분 확인, 하나의 키로 암호화/복호화를 수행하는 대칭키 암호화 방식 등

 

 

1. 먼저 클라이언트가 서버에 접속해 말을 걸면서 몇가지 정보를 제공한다.

  • 브라우저가 사용하는 SSL혹은TLS 버전 정보
  • 브라우저가 지원하는 암호화 방식
  • 브라우저가 임의로 생성한 난수

2. 서버도 인사에 응답하고, 다음 정보를 클라이언트에게 제공한다.

  • 서버의 공개키가 담긴 SSL 인증서
  • 서버가 임의로 생성한 난수

 

3. 브라우저는 서버가 제공한 SSL인증서가 믿을만한지 확인

  • CA공개키를 가지고 암호화된 SSL인증서를 복호화해서 확인

 

4. 브라우저의 난수 값과 서버에서 받은 난수 값을 이영해 premaster secret 값을 생성

 

5. 서버는 사이트의 비밀키로 받은 premaster secret 값을 복호화 한다.

  • 서버는 premaster secret 값을 master key로 저정해 session key를 만들고 이 키를 이용해 데이터의 암호화/복호화를 진행한다.

 

6. SSL handshake를 종료하고, HTTPS 통신을 시작

  • 브러우저와 서버는 SSL handshake를 정상적으로 완료하고, 웹상에서 데이터를 세션키를 통해 암호화/복호화하면서 HTTPS통해 주고 받는다.

'WEB > WebSocket' 카테고리의 다른 글

NameSpace 설정하기  (0) 2024.05.10
(WebSocket) NestJS 채팅 어플리케이션 만들기  (0) 2024.05.04

스프레드

스프레드(spread)  전개 문법 ...은 뭉쳐 있는 여러 값들의 집합을 펼쳐서 개별적인 값들의 목록으로 만든다.

이터러블이 아닌 객체는 사용할 수 없다.(하지만 스프레드 프로퍼티를 제안 받으면 가능하다.)

결과 값이 값들의 목록이라서 문법의 결과는 변수에 할당할 수 없다.

 

 

const arr = [1,2];
const arr2 = [3,4];
const newArr = arr.concat(arr2);
console.log(newArr);
const newArr2 = [...arr, ...arr2]; //[1,2,3,4]
console.log(newArr2);

 

 

const arr = [1,4];
const arr2 = [2,3];
arr.splice(1, 0, ...arr2);
console.log(arr); // [1,2,3,4]

'WEB > JS' 카테고리의 다른 글

[JS] 이터러블  (0) 2024.01.01
[JS] 배열 고차 함수  (0) 2023.12.26
[JS] 배열 메서드(2)  (0) 2023.12.26
[JS] 배열 메서드(1)  (0) 2023.12.25
[JS] Rest 파라미터  (0) 2023.12.24

이터러블

 

  • 자료를 반복할 수 있는 객체 ex) 배열
  • 이터러블 프로토콜을 준수한 객
  • 이터레이터 메서드(Symbol.iterator)를 반환하는 객체

 

// 배열은 이터러블 프로토콜을 준수한다.
const arr = [1,2,3];
for(item of arr){
    console.log(item);
}

// 일반 객체를 이터러블 프로토콜을 준수하지 않아서 for...of 같은 메서드를 사용할 수 없다.

const obj = {
    a: 1,
    b: 2
};
for(item of obj){
    console.log(item); //TypeError: obj is not iterable
}

 

 

이터레이터

 

이터러블을 호출하면 이터레이터 프로토콜을 준수하는 객체

next()객체를 갖는다.

 

next()

  • 이터러블의 각 요소를 순회하기 위한 포인터 역할
  • 순회하면서 순차적으로  순회 결과를 이터레이터 리절트 객체를 반환한다.
  • 프로퍼티로 value : 현재 값, done : 순회 가능 여부로 이루어져 있다.

 

const iterator = arr[Symbol.iterator]();
console.log(iterator.next()); //{value: 1, done: false}
console.log(iterator.next()); //{value: 2, done: false}
console.log(iterator.next()); //{value: 3, done: false}
console.log(iterator.next()); //{value: undefined, done: true}

'WEB > JS' 카테고리의 다른 글

[JS] 스프레드 문법  (0) 2024.01.01
[JS] 배열 고차 함수  (0) 2023.12.26
[JS] 배열 메서드(2)  (0) 2023.12.26
[JS] 배열 메서드(1)  (0) 2023.12.25
[JS] Rest 파라미터  (0) 2023.12.24

sort

 

배열의 요소를 정렬한다. 기본값 오름차순, 원본 배열 변경된다.

 

const fruits = ['Banana', 'Orange', 'Apple'];
fruits.sort();
console.log(fruits); // [Apple, Banana, Orange]
fruits.reverse();
console.log(fruits); // [Orange, Banana, Apple]

 

 

 

forEach

 

forEach(요소, 인덱스, 배열), for의 확장판

 

const numbers = [1,2,3,4,5];
const pows = [];

numbers.forEach((item) => pows.push(item ** 2));
console.log(pows);
numbers.forEach((item, index, arr) => {
    console.log(`${item} 은 ${arr}의 ${index}번째 요소이다.`);
});

 

 

 

map

 

호출한 배열의 모든 요소를 순회하면서 인수로 전달받은 콜백 함수를 반복 호출한다. 원본 배열을 변경되지 않고 새로운 배열을 반환한다.

 

 

const numbers = [1,2,3,4,5];

const roots = numbers.map((item) => {
    return Math.sqrt(item);
});
console.log(roots);

 

 

 

filter

 

자신을 호출한 배열의 모든 요소를 순회하면서 콜백 함수의 반환값이 true인 요소로만 구성된 새로운 배열을 반환한다. 원본 배열을 변경되지 않는다.

 

 

const numbers = [1,2,3,4,5];

const odds = numbers.filter((item) => {
    return item % 2;
})
console.log(odds);

 

 

reduce

 

배열의 모든 요소를 순회하면서 누적된 값을 반환한다.

reduce(초기값(0), 현재값, 인덱스, 배)

 

 

const numbers = [1,2,3,4,5];
let result = numbers.reduce((cnt, item) =>{
    return cnt += item;
})
console.log(result); // 15

'WEB > JS' 카테고리의 다른 글

[JS] 스프레드 문법  (0) 2024.01.01
[JS] 이터러블  (0) 2024.01.01
[JS] 배열 메서드(2)  (0) 2023.12.26
[JS] 배열 메서드(1)  (0) 2023.12.25
[JS] Rest 파라미터  (0) 2023.12.24

slice

 

인수로 전달된 범위의 요소들을 복사하여 배열로 반환한다, 원본 배열은 변경되지 않는다.

slice(startIndex, endIndex)

  • startIndex : 시작할 인덱스이다, 음수인 경우 배열의 끝에서 갯수를 나타낸다.
  • endIndex : 종료할 인덱스이다, 해당 값의 전까지 복사한다, 생략할 경우 최대길이(length) 까지다.

 

const arr = [1,2,3];
let result = arr.slice(0,2);
console.log(result) // [1,2]
console.log(arr); [1,2,3]
result = arr.slice(-1);
console.log(result); // 3

 

 

join

 

원본 배열의 모든 요소를 문자열로 변환한 후 구분자로 연결한 문자열을 반환한다.

기본 구분자는 콤마(',')이다.

 

 

const arr = [1,2,3,4,5];
let result = arr.join();
console.log(result); // 1,2,3,4,5
result = arr.join(':');
console.log(result); // 1:2:3:4:5

 

 

reverse

 

원본 배열의 순서를 반대로 뒤집는다. 변경된 배열이 반환된다, 원본 배열이 변경된다.

 

 

const arr = [1,2,3,4];
arr.reverse();
console.log(arr); // [4,3,2,1]

 

 

 

fill

 

인수로 전달받은 값을 배열의 처음부터 끝까지 요소로 채운다. 원본 배열이 변경된다.

 

 

const arr = [1,2,3,4,5];
arr.fill(0);
console.log(arr); // [0,0,0,0,0]

const arr2 = [1,2,3,4,5];
arr2.fill(0,2, 4);
console.log(arr2); // [1,2,0,0,5]

 

 

 

'WEB > JS' 카테고리의 다른 글

[JS] 이터러블  (0) 2024.01.01
[JS] 배열 고차 함수  (0) 2023.12.26
[JS] 배열 메서드(1)  (0) 2023.12.25
[JS] Rest 파라미터  (0) 2023.12.24
[JS] 화살표 함수  (0) 2023.12.20

 

Array.isArray

 

전달된 인수가 배열이면 true, 배열이 아니면 false를 반환한다.

 

Array.isArray([1,2,3]); //true
Array.isArray(new Array()); //true
Array.isArray({}); //false
Array.isArray(null); //false

 

 

indexOf / includes

 

indexOf : 원본 배열에서 전달된 요소를 검색하여 인덱스를 반환하고 없으면 -1을 반환한다.

 

let arr = [1,2,3,4,5];
console.log(arr.indexOf(2)); // 1
console.log(arr.indexOf(8)); // -1

 

 

includes : 전달된 요소를 검색해서 boolean값을 반환한다.

 

let food = ['apple', 'orange', 'banana'];
console.log(food.includes('apple')); //true
console.log(food.includes('melon')); //false

 

 

push

 

인수로 전달받은 모든 값을 원본 배열의 마지막 요소로 추가하고 변경된 length값을 반환한다, 원본 배열을 직접 변경한다.

 

const arr = [1,2,3,4];
let result = arr.push(5,6);
console.log(result); // 6
console.log(arr); // [1,2,3,4,5,6]

 

 

pop

 

원본 배열에서 마지막 요소를 제거하고 제거한 요소를 반환한다, 빈 배열이면 undefined를 반환화고 원본 배열을 직접 변경한다.

 

const arr = [1,2,3,4];
const result = arr.pop();
console.log(result); // 4
console.log(arr); // [1,2,3]

 

 

unshift

 

인수로 전달받은 모든 값을 원본 배열의 선두에 요소로 추가하고 변경된 length값을 반환한다.

 

const arr = [3,4];
let result = arr.unshift(1,2);
console.log(result); // 4
console.log(arr); // [1,2,3,4]

 

 

shift

 

원본 배열에서 첫 번째 요소를 제거하고 제거한 요소를 반환한다.

 

const arr = [1,2,3,4,5];
let result = arr.shift();
console.log(result); // 1
console.log(arr); // [2,3,4,5]

 

 

concat

 

인수로 전달된 값들을 원본 배열의 마지막 요소로 추가하고 새로운 배열을 반환한다. 원본 배열을 변경되지 않는다.

 

const arr = [1,2];
const arr2 = [3,4];
let arr3 = arr.concat(arr2);
console.log(arr3); // [1,2,3,4]

 

 

splice

 

특정 번지에 있는 요소부터 제거하고 변경한다, 제거된 요소들이 반환된다.

splice(시작번지, 제거할 갯수, 추가할 값1, 추가할 값2, ......)

 

const arr = [1,2,3,4,5,6,7,8];
let result = arr.splice(1,3,10,20,30);
console.log(result); // [2,3,4]
console.log(arr); // [1,10,20,30,....];

'WEB > JS' 카테고리의 다른 글

[JS] 배열 고차 함수  (0) 2023.12.26
[JS] 배열 메서드(2)  (0) 2023.12.26
[JS] Rest 파라미터  (0) 2023.12.24
[JS] 화살표 함수  (0) 2023.12.20
[JS] 클로저  (0) 2023.12.15

+ Recent posts