AWS Lambda,API Gateway를 이용한 채팅 서버 만들기

김유신·2024년 3월 3일

AWS Lambda,API Gateway를 이용한 채팅 서버 만들기

람다 함수를 생성합니다. 노드 16번대 버전으로 진행 하였습니다.

Lamda 함수에 사용할 코드입니다.

Lambda 함수로 작성된 AWS API Gateway의 WebSocket 연결을 처리하고 클라이언트 간 메시지를 전송,사용자 연결을 관리합니다.

const AWS = require('aws-sdk');

const ENDPOINT = '[ednpoint]]';
const client = new AWS.ApiGatewayManagementApi({ endpoint: ENDPOINT });
const names = {};

const sendTo = async (id, body) => {
    try {
        await client.postToConnection({
            'ConnectionId': id,
            'Data': Buffer.from(JSON.stringify(body)),
        }).promise();
    } catch (err) {
        console.error(err);
    }
};

const sendToAll = async (ids, body) => {
    const all = ids.map(i => sendTo(i, body));
    return Promise.all(all);
};

exports.handler = async (event) => {
    if (!event.requestContext) {
        return {};
    }

    try {
        const connectionId = event.requestContext.connectionId;
        const routeKey = event.requestContext.routeKey;
        const body = JSON.parse(event.body || '{}');

        switch (routeKey) {
            case "$connect": break;
            case "$disconnect": delete names[connectionId]; break;

            default:
                switch (body.action) {
                    case "login": names[connectionId] = body.name; break;
                    case "sednTo": await sendTo(connectionId, body); break;
                    case "sendToAll": await sendToAll(Object.keys(names), body); break;
                }
        }
    } catch (err) {
        console.error(err);
    }

    return {};
};

aws-sdk 라이브러리를 가져오고, WebSocket 연결 관리를 위한 API Gateway 엔드포인트와 클라이언트 객체를 생성합니다.

const ENDPOINT = '[ednpoint]]'; 부분에 API Gateway의 엔드 포인트를 넣을 예정입니다.

names 객체는 연결된 클라이언트의 ConnectionId와 사용자 이름을 관리하는 데 사용됩니다. 추후에 다이나모 db와 연동 예정이기에 테스트 용입니다.

sendTo 함수 정의로 특정 ConnectionId를 가진 클라이언트에게 메시지를 전송하는 역할을 합니다.
sendToAll 함수 정의로 모든 연결된 클라이언트에게 메시지를 전송하는 역할을 합니다.

Lambda 핸들러 함수 정의로
WebSocket 이벤트에 대한 처리를 담당합니다.

$ connect 이벤트는 클라이언트가 연결되었을 때 호출됩니다.
$ disconnect 이벤트는 클라이언트가 연결을 끊었을 때 호출됩니다.

기타 이벤트는 클라이언트 간 메시지 전송 및 사용자 관리 등을 수행합니다.


만든 Lambda 함수에 코드 소스를 넣어 줍니다.

API Gateway로 이동해 WebSocket API를 구축합니다.

API 이름은 chat 라우팅 선택 표현식은 request.body.action (default)로 설정했습니다.

경로는 $connect $disconnect $default 3개 경로를 추가 했습니다.

경로마다 생성한 chat 람다 함수를 연결해 주었습니다.

스테이지 추가는 기본으로 만들어진 production을 사용했습니다. 이후 생성및 배포를 진행한뒤 생성한 API gateway의
스테이지에서 WebSocket URL을 확인합니다.

람다로 돌아와 API wss://를 제외한 뒷부분을 엔드포인트 부분에 넣어준 뒤 Deploy 해줍니다.

이후 구성 탭으로 넘어와 권한으로 이동한 뒤 역할 이름을 클릭하여 적당한 역할을 생성 권한을 부여합니다.
(APIGateWayInvikeFullAccess) APIGateway
풀 엑세스를 부여했습니다.

채팅서버가 완료되었습니다.
ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ

테스트 ㅡ

APIGateway에서 WebSocket의 주소를 wss://를 포함해 복사합니다.
터미널 혹은 콘솔에서 아래 명령어를 통해 웹소캣 클라이언트 프로그램을 설치합니다.

npm install -g wscat

테스트를 하기 위해 2개의 cmd에서 wscat -c 소캣 주소를 입력합니다. 정상적으로 연결되어 Connected가 표시 되었습니다.

코드중 로그인 부분을 json 포멧을 사용하여 입력한뒤
sendToAll 액션으로 메세지를 전송하면 자신과 다른 사용자에게 메세지가 전달되는것을 확인 할수 있습니다.

반대편 콘솔에서 보낸 메세지도 수신되는것을 확인 할 수 있습니다.

profile
KYS's blog

0개의 댓글