> For the complete documentation index, see [llms.txt](https://jakekwak.gitbook.io/nestjs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://jakekwak.gitbook.io/nestjs/websockets/gateways.md).

# Gateways

## Gateways

게이트웨이는 `@WebSocketGateway()`데코레이터로 주석이 달린 클래스입니다. 게이트웨이는 기본적으로 [socket.io](https://github.com/socketio/socket.io) 패키지를 사용하지만 기본 웹 소켓 구현을 포함하여 광범위한 다른 라이브러리와의 호환성을 제공합니다. [여기](https://app.gitbook.com/websockets/adapter).

> warning **힌트** 게이트웨이는 단순한 **공급자**와 동일하게 작동하므로 생성자를 통해 손쉽게 종속성을 주입 할 수 있습니다. 또한 게이트웨이는 다른 클래스 (공급자 및 컨트롤러)에 의해 주입 될 수도 있습니다.

## Installation

먼저 필요한 패키지를 설치해야합니다.

```bash
@@filename()
$ npm i --save @nestjs/websockets @nestjs/platform-socket.io
$ npm i --save-dev @types/socket.io
@@switch
$ npm i --save @nestjs/websockets @nestjs/platform-socket.io
```

## Overview

일반적으로 앱이 웹 응용 프로그램이 아니거나 수동으로 포트를 변경하지 않은 경우 각 게이트웨이는 **HTTP 서버**가 실행되는 것과 동일한 포트를 수신합니다. `@WebSocketGateway(80)`데코레이터에 인수를 전달하여 이 동작을 변경할 수 있습니다. 여기서 `80`은 선택된 포트 번호입니다. 또한 다음 구성으로 이 게이트웨이에서 사용하는 [namespace](https://socket.io/docs/rooms-and-namespaces/)를 설정할 수 있습니다.

```typescript
@WebSocketGateway(80, { namespace: 'events' })
```

> **경고** 게이트웨이는 `providers` 배열 안에 넣을 때까지 시작되지 않습니다.

`네임 스페이스`는 유일하게 사용 가능한 옵션이 아닙니다. [여기](https://socket.io/docs/server-api/)에 언급된 다른 속성을 전달할 수 있습니다. 이러한 속성은 인스턴스화 프로세스 동안 소켓 생성자로 전달됩니다.

```typescript
@WebSocketGateway(81, { transports: ['websocket'] })
```

좋아, 게이트웨이는 지금 듣고 있지만 우리는 지금까지 들어오는 메시지를 subscript하지 않습니다. `events` 메시지를 subscription하고 똑같은 데이터로 사용자에게 응답하는 핸들러를 만들어 봅시다.

```typescript
@@filename(events.gateway)
@SubscribeMessage('events')
handleEvent(client: Client, data: string): string {
  return data;
}
@@switch
@SubscribeMessage('events')
handleEvent(client, data) {
  return data;
}
```

> info **힌트** `@SubscribeMessage()`데코레이터는 `@nestjs/websockets` 패키지에서 가져옵니다.

`handleEvent()`함수는 두 개의 인수를 취합니다. 첫번째는 플랫폼 별 [소켓 인스턴스](https://socket.io/docs/server-api/#socket)이고 두 번째는 클라이언트에서 받은 데이터입니다. 메시지를 받으면 누군가가 네트워크를 통해 보낸 것과 동일한 데이터로 승인을 보냅니다. 또한 라이브러리 별 접근 방식을 사용하여, 예를 들어 `client.emit()`메소드를 사용하여 메시지를 생성할 수 있습니다. 그러나 이 경우 인터셉터를 사용할 수 없습니다. 사용자에게 응답하지 않으려면 아무 것도 반환하지 마십시오 (또는 "정의되지 않은"과 같이 "거짓"값을 명시적으로 반환).

이제 클라이언트가 다음과 같은 방식으로 메시지를 보낼 때

```typescript
socket.emit('events', { name: 'Nest' });
```

`handleEvent()`메소드가 실행됩니다. 위 핸들러 내에서 생성된 메시지를 들으려면 클라이언트가 해당 승인 리스너를 첨부해야합니다.

```typescript
socket.emit('events', { name: 'Nest' }, data => console.log(data));
```

## Multiple responses

승인은 한번만 발송됩니다. 또한 기본 WebSockets 구현에서는 지원되지 않습니다. 이 제한을 해결하기 위해 두 가지 속성으로 구성된 객체를 반환할 수 있습니다. 생성된 이벤트의 이름인 `event`와 클라이언트에 전달해야 하는 `data`입니다.

```typescript
@@filename(events.gateway)
@SubscribeMessage('events')
handleEvent(client: Client, data: unknown): WsResponse<unknown> {
  const event = 'events';
  return { event, data };
}
@@switch
@SubscribeMessage('events')
handleEvent(client, data) {
  const event = 'events';
  return { event, data };
}
```

> info **힌트** `WsResponse` 인터페이스는 `@nestjs/websockets` 패키지에서 가져옵니다.

들어오는 응답을 들으려면 클라이언트가 다른 이벤트 리스너를 적용해야합니다.

```typescript
socket.on('events', data => console.log(data));
```

## Asynchronous responses

각 메시지 핸들러는 동기식 또는 **비동기식** (`async`) 일 수 있으므로 `Promise`를 반환할 수 있습니다. 또한 [Observable](https://github.com/reactivex/rxjs)을 반환 할 수 있습니다. 즉, 여러 값을 반환할 수 있습니다 (스트림이 완료 될 때까지 방출 됨).

```typescript
@@filename(events.gateway)
@SubscribeMessage('events')
onEvent(client: Client, data: unknown): Observable<WsResponse<number>> {
  const event = 'events';
  const response = [1, 2, 3];

  return from(response).pipe(
    map(data => ({ event, data })),
  );
}
@@switch
@SubscribeMessage('events')
onEvent(client, data) {
  const event = 'events';
  const response = [1, 2, 3];

  return from(response).pipe(
    map(data => ({ event, data })),
  );
}
```

위의 메시지 처리기는 **3 번** (순서대로 `response`배열의 각 항목과 함께) 응답합니다.

## Lifecycle hooks

3 가지 유용한 수명주기 후크가 있습니다. 모두 해당 인터페이스가 있으며 다음 표에 설명되어 있습니다.

| `OnGatewayInit`       | `afterInit()` 메소드를 강제로 구현합니다. 라이브러리 특정 서버 인스턴스를 인수로 사용합니다. (필요한 경우 나머지를 확산시킵니다). |
| --------------------- | -------------------------------------------------------------------------------- |
| `OnGatewayConnection` | `handleConnection()` 메소드를 강제로 구현합니다. 라이브러리 특정 클라이언트 소켓 인스턴스를 인수로 사용합니다.          |
| `OnGatewayDisconnect` | `handleDisconnect()` 메소드를 강제로 구현합니다. 라이브러리 특정 클라이언트 소켓 인스턴스를 인수로 사용합니다.          |

> info **힌트** 각 라이프 사이클 인터페이스는`@nestjs/websockets` 패키지에서 공개됩니다.

## Server

경우에 따라 **플랫폼 별** 기본 서버 인스턴스에 직접 액세스 할 수 있습니다. 이 객체에 대한 참조는 `afterInit()`메소드 (`OnGatewayInit` 인터페이스)에 인수로 전달됩니다. 두 번째 방법은 `@WebSocketServer()`데코레이터를 사용하는 것입니다.

```typescript
@WebSocketServer()
server: Server;
```

> warning **알림** `@WebSocketServer()`데코레이터는 `@nestjs/websockets` 패키지에서 가져옵니다.

Nest는 사용할 준비가 되면 서버 인스턴스를 이 속성에 자동으로 할당합니다.

## Example

실제 사례는 [여기](https://github.com/nestjs/nest/tree/master/sample/02-gateways)에서 확인할 수 있습니다.
