Skip to content

AWS에서 SST를 사용한 실시간 앱 구축

SST를 사용하여 실시간 채팅 앱을 AWS에 배포하는 방법을 알아봅니다.

AWS에서 SST를 사용한 실시간 앱 만들기

SST를 사용하여 AWS에 실시간 채팅 앱을 구축하고 배포해 보겠습니다.

시작하기 전에 AWS 자격 증명을 설정했는지 확인하세요.


1. 프로젝트 생성

Node.js 앱을 만들어 보겠습니다.

Terminal window
npx create-next-app@latest my-realtime-app
cd my-realtime-app

SST 초기화

이제 앱에서 SST를 초기화해 보겠습니다.

Terminal window
npx sst@latest init
npm install

기본값을 선택하고 AWS를 선택합니다. 이렇게 하면 프로젝트 루트에 sst.config.ts 파일이 생성됩니다.


개발 모드 시작

개발 모드를 시작하려면 다음 명령어를 실행하세요. 이 명령은 SST와 Next.js 앱을 동시에 실행합니다.

Terminal window
npx sst dev

실행이 완료되면 사이드바에서 MyWeb을 클릭하고 브라우저에서 Next.js 앱을 열어보세요.

2. 실시간 기능 추가

Realtime 컴포넌트를 추가하고 Next.js 앱과 연결해 보겠습니다. sst.config.ts 파일을 업데이트하세요.

sst.config.ts
async run() {
const realtime = new sst.aws.Realtime("MyRealtime", {
authorizer: "authorizer.handler",
});
new sst.aws.Nextjs("MyWeb", {
link: [realtime],
});
},

이 컴포넌트를 사용하면 구독할 수 있는 _토픽_을 설정할 수 있습니다. authorizer 함수는 누가 이 토픽에 접근할 수 있는지 제어하는 데 사용됩니다.

인증자 추가하기

프로젝트 루트에 새로운 authorizer.ts 파일을 만들고 다음 내용을 추가하세요.

authorizer.ts
import { Resource } from "sst";
import { realtime } from "sst/aws/realtime";
export const handler = realtime.authorizer(async (token) => {
const prefix = `${Resource.App.name}/${Resource.App.stage}`;
const isValid = token === "PLACEHOLDER_TOKEN";
return isValid
? {
publish: [`${prefix}/*`],
subscribe: [`${prefix}/*`],
}
: {
publish: [],
subscribe: [],
};
});

여기서는 유효한 토큰을 가진 사용자가 앱과 스테이지 이름으로 네임스페이스된 모든 토픽에 대해 발행(publish) 및 구독(subscribe)할 수 있는 권한을 부여합니다.

프로덕션 환경에서는 주어진 토큰을 데이터베이스나 인증 프로바이더와 대조하여 검증해야 합니다.


3. 채팅 UI 만들기

이제 앱에 채팅 인터페이스를 만들어 보겠습니다. components/chat.tsx에 새로운 컴포넌트를 생성하고 다음 코드를 추가합니다.

components/chat.tsx
"use client";
import mqtt from "mqtt";
import { useState, useEffect } from "react";
import styles from "./chat.module.css";
export default function Chat(
{ topic, endpoint, authorizer }: { topic: string, endpoint: string, authorizer: string }
) {
const [messages, setMessages] = useState<string[]>([]);
const [connection, setConnection] = useState<mqtt.MqttClient | null>(null);
return (
<div className={styles.chat}>
{connection && messages.length > 0 &&
<div className={styles.messages}>
{messages.map((msg, i) => (
<div key={i}>{msg}</div>
))}
</div>
}
<form
className={styles.form}
onSubmit={async (e) => {
e.preventDefault();
const input = (e.target as HTMLFormElement).message;
connection!.publish(topic, input.value, { qos: 1 });
input.value = "";
}}
>
<input
required
autoFocus
type="text"
name="message"
placeholder={
connection ? "Ready! Say hello..." : "Connecting..."
}
/>
<button type="submit" disabled={connection === null}>Send</button>
</form>
</div>
);
}

여기서는 주어진 토픽에 제출된 메시지를 발행할 것입니다. 실시간 연결은 아래에서 만들겠습니다.

스타일을 추가합니다.

components/chat.module.css
.chat {
gap: 1rem;
width: 30rem;
display: flex;
padding: 1rem;
flex-direction: column;
border-radius: var(--border-radius);
background-color: rgba(var(--callout-rgb), 0.5);
border: 1px solid rgba(var(--callout-border-rgb), 0.3);
}
.messages {
padding-bottom: 0.125rem;
border-bottom: 1px solid rgba(var(--callout-border-rgb), 0.3);
}
.messages > div {
line-height: 1.1;
padding-bottom: 0.625rem;
}
.form {
display: flex;
gap: 0.625rem;
}
.form input {
flex: 1;
font-size: 0.875rem;
padding: 0.5rem 0.75rem;
border-radius: calc(1rem - var(--border-radius));
border: 1px solid rgba(var(--callout-border-rgb), 1);
}
.form button {
font-weight: 500;
font-size: 0.875rem;
padding: 0.5rem 0.75rem;
border-radius: calc(1rem - var(--border-radius));
background: linear-gradient(
to bottom right,
rgba(var(--tile-start-rgb), 1),
rgba(var(--tile-end-rgb), 1)
);
border: 1px solid rgba(var(--callout-border-rgb), 1);
}
.form button:active:enabled {
background: linear-gradient(
to top left,
rgba(var(--tile-start-rgb), 1),
rgba(var(--tile-end-rgb), 1)
);
}

npm 패키지를 설치합니다.

Terminal window
npm install mqtt

페이지에 추가하기

이제 우리의 페이지에서 컴포넌트를 사용해 보겠습니다. app/page.tsx 파일의 Home 컴포넌트를 아래 코드로 교체하세요.

app/page.tsx
import { Resource } from "sst";
import Chat from "@/components/chat";
const topic = "sst-chat";
export default function Home() {
return (
<main className={styles.main}>
<div className={styles.center}>
<Image
className={styles.logo}
src="/next.svg"
alt="Next.js Logo"
width={180}
height={37}
priority
/>
</div>
<div>
<Chat
endpoint={Resource.MyRealtime.endpoint}
authorizer={Resource.MyRealtime.authorizer}
topic={`${Resource.App.name}/${Resource.App.stage}/${topic}`}
/>
</div>
</main>
);
}

여기서는 앱 이름과 배포된 스테이지 아래에 네임스페이스로 지정된 sst-chat라는 _토픽_에 게시하고 구독할 것입니다.


4. 연결 생성하기

채팅 컴포넌트가 로드되면 실시간 서비스에 새로운 연결을 생성합니다. components/chat.tsx 파일의 import 아래에 다음 코드를 추가하세요.

components/chat.tsx
function createConnection(endpoint: string, authorizer: string) {
return mqtt.connect(`wss://${endpoint}/mqtt?x-amz-customauthorizer-name=${authorizer}`, {
protocolVersion: 5,
manualConnect: true,
username: "", // 인증자에 대해 비워둬야 함
password: "PLACEHOLDER_TOKEN", // 인증자에 토큰으로 전달됨
clientId: `client_${window.crypto.randomUUID()}`,
});
}

여기서는 플레이스홀더 토큰을 사용합니다. 실제 프로덕션 환경에서는 사용자의 세션 토큰일 수 있습니다.

이제 연결을 구독하고 받은 메시지를 저장해 보겠습니다. Chat 컴포넌트에 다음 코드를 추가하세요.

components/chat.tsx
useEffect(() => {
const connection = createConnection(endpoint, authorizer);
connection.on("connect", async () => {
try {
await connection.subscribeAsync(topic, { qos: 1 });
setConnection(connection);
} catch (e) { }
});
connection.on("message", (_fullTopic, payload) => {
const message = new TextDecoder("utf8").decode(new Uint8Array(payload));
setMessages((prev) => [...prev, message]);
});
connection.on("error", console.error);
connection.connect();
return () => {
connection.end();
setConnection(null);
};
}, [topic, endpoint, authorizer]);

브라우저에서 로컬 Next.js 앱(http://localhost:3000)으로 이동하여 메시지를 보내보세요. 메시지가 즉시 나타나는 것을 확인할 수 있습니다. 새로운 브라우저 창을 열어 두 곳에서 모두 메시지가 나타나는지 확인할 수도 있습니다.


5. 앱 배포하기

이제 여러분의 앱을 AWS에 배포해 보겠습니다.

Terminal window
npx sst deploy --stage production

여기서는 어떤 스테이지 이름을 사용해도 되지만, 프로덕션을 위해 새로운 스테이지를 만드는 것이 좋습니다.

축하합니다! 이제 여러분의 앱이 라이브 상태가 되었습니다!

SST Realtime Next.js 앱

다음으로 할 수 있는 작업은 다음과 같습니다:

  • 사용자가 채팅방을 만들 수 있도록 하기
  • 채팅방을 데이터베이스에 저장하기
  • 올바른 채팅방의 메시지만 보여주기

이렇게 하면 프로덕션용 실시간 앱을 구축하는 데 도움이 될 것입니다.


콘솔 연결하기

다음 단계로 SST 콘솔을 설정하여 _git push로 앱을 배포_하고 문제를 모니터링할 수 있습니다.

SST 콘솔 자동 배포

무료 계정을 생성하고 AWS 계정에 연결할 수 있습니다.