이 Codelab에서는 푸시 알림 서버를 빌드하는 방법을 단계별로 보여줍니다. 이 Codelab을 마치면 다음과 같은 서버가 생성됩니다.
- 푸시 알림 구독을 추적합니다.즉, 클라이언트가 푸시 알림을 선택하면 서버는 새 데이터베이스 레코드를 만들고 클라이언트가 선택 해제하면 기존 데이터베이스 레코드를 삭제합니다.
- 단일 클라이언트에 푸시 알림 전송
- 구독 중인 모든 클라이언트에 푸시 알림을 전송합니다.
이 Codelab에서는 직접 해 보면서 학습하는 데 중점을 두며 개념에 대해서는 많이 다루지 않습니다. 푸시 알림은 어떻게 작동하나요?를 확인하여 푸시 알림 개념을 알아보세요.
이 Codelab의 클라이언트 코드는 이미 완성되어 있습니다. 이 Codelab에서는 서버만 구현합니다. 푸시 알림 클라이언트를 구현하는 방법을 알아보려면 Codelab: 푸시 알림 클라이언트 빌드를 확인하세요.
전체 코드는 push-notifications-server-codelab-complete(소스)를 확인하세요.
브라우저 호환성
이 Codelab은 다음 운영체제 및 브라우저 조합에서 작동하는 것으로 알려져 있습니다.
- Windows: Chrome, Edge
- macOS: Chrome, Firefox
- Android: Chrome, Firefox
이 Codelab은 다음 운영체제(또는 운영체제와 브라우저 조합)에서는 작동하지 않는 것으로 알려져 있습니다.
- macOS: Brave, Edge, Safari
- iOS
애플리케이션 스택
- 서버는 Express.js를 기반으로 빌드됩니다.
- web-push Node.js 라이브러리는 모든 푸시 알림 로직을 처리합니다.
- 구독 데이터는 lowdb를 사용하여 JSON 파일에 작성됩니다.
푸시 알림을 구현하기 위해 이러한 기술을 사용할 필요는 없습니다. 이러한 기술을 선택한 이유는 안정적인 Codelab 환경을 제공하기 때문입니다.
설정
수정 가능한 코드 사본 받기
이 안내 오른쪽에 표시되는 코드 편집기는 이 Codelab에서 Glitch UI라고 합니다.
- 수정할 리믹스를 클릭하여 프로젝트를 수정할 수 있도록 합니다.
인증 설정
푸시 알림을 사용하려면 먼저 인증 키로 서버와 클라이언트를 설정해야 합니다. 이유를 알아보려면 웹 푸시 프로토콜 요청 서명을 참고하세요.
- 도구를 클릭한 다음 터미널을 클릭하여 Glitch 터미널을 엽니다.
- 터미널에서
npx web-push generate-vapid-keys
를 실행합니다. 비공개 키와 공개 키 값을 복사합니다. .env
를 열고VAPID_PUBLIC_KEY
및VAPID_PRIVATE_KEY
를 업데이트합니다.VAPID_SUBJECT
을mailto:test@test.test
로 설정합니다. 이러한 값은 모두 큰따옴표로 묶어야 합니다. 업데이트한 후.env
파일은 다음과 유사합니다.
VAPID_PUBLIC_KEY="BKiwTvD9HA…"
VAPID_PRIVATE_KEY="4mXG9jBUaU…"
VAPID_SUBJECT="mailto:test@test.test"
- Glitch 터미널을 닫습니다.
public/index.js
를 엽니다.VAPID_PUBLIC_KEY_VALUE_HERE
를 공개 키 값으로 바꿉니다.
구독 관리
클라이언트가 대부분의 구독 프로세스를 처리합니다. 서버에서 해야 하는 주요 작업은 새 푸시 알림 구독을 저장하고 이전 구독을 삭제하는 것입니다. 이러한 구독을 통해 나중에 클라이언트에 메시지를 푸시할 수 있습니다. 정기 결제 프로세스에 관한 자세한 내용은 클라이언트의 푸시 알림 구독을 참고하세요.
새 정기 결제 정보 저장
- 사이트를 미리 보려면 앱 보기를 누른 다음 전체 화면을 누릅니다.
- 앱 탭에서 등록 서비스 워커를 클릭합니다. 상태 상자에 다음과 유사한 메시지가 표시됩니다.
Service worker registered. Scope: https://desert-cactus-sunset.glitch.me/
- 앱 탭에서 푸시 구독을 클릭합니다. 브라우저 또는 운영 체제에서 웹사이트에서 푸시 알림을 보내도록 허용할지 묻는 메시지가 표시될 수 있습니다. 허용 (또는 브라우저/OS에서 사용하는 이에 상응하는 문구)을 클릭합니다. 상태 상자에 다음과 유사한 메시지가 표시됩니다.
Service worker subscribed to push. Endpoint: https://fcm.googleapis.com/fcm/send/…
- Glitch UI에서 소스 보기를 클릭하여 코드로 돌아갑니다.
- 도구를 클릭한 다음 로그를 클릭하여 Glitch 로그를 엽니다.
/add-subscription
뒤에 데이터가 표시됩니다./add-subscription
는 클라이언트가 푸시 알림을 구독하려고 할 때 POST 요청을 보내는 URL입니다. 다음 데이터는 저장해야 하는 클라이언트의 정기 결제 정보입니다. server.js
를 엽니다.- 다음 코드를 사용하여
/add-subscription
경로 핸들러 로직을 업데이트합니다.
app.post('/add-subscription', (request, response) => {
console.log('/add-subscription');
console.log(request.body);
console.log(`Subscribing ${request.body.endpoint}`);
db.get('subscriptions')
.push(request.body)
.write();
response.sendStatus(200);
});
이전 정기 결제 정보 삭제
- 앱 탭으로 돌아갑니다.
- 푸시 구독 취소를 클릭합니다.
- Glitch 로그를 다시 확인합니다.
/remove-subscription
다음에 클라이언트의 구독 정보가 표시됩니다. - 다음 코드로
/remove-subscription
경로 핸들러 로직을 업데이트합니다.
app.post('/remove-subscription', (request, response) => {
console.log('/remove-subscription');
console.log(request.body);
console.log(`Unsubscribing ${request.body.endpoint}`);
db.get('subscriptions')
.remove({endpoint: request.body.endpoint})
.write();
response.sendStatus(200);
});
알림 보내기
푸시 메시지 보내기에서 설명한 대로 서버는 실제로 푸시 메시지를 클라이언트로 직접 전송하지 않습니다. 대신 푸시 서비스를 사용합니다. 서버는 기본적으로 사용자가 사용하는 브라우저 공급업체가 소유한 웹 서비스 (푸시 서비스)에 웹 서비스 요청 (웹 푸시 프로토콜 요청)을 실행하여 클라이언트에 메시지를 푸시하는 프로세스를 시작합니다.
- 다음 코드로
/notify-me
경로 핸들러 로직을 업데이트합니다.
app.post('/notify-me', (request, response) => {
console.log('/notify-me');
console.log(request.body);
console.log(`Notifying ${request.body.endpoint}`);
const subscription =
db.get('subscriptions').find({endpoint: request.body.endpoint}).value();
sendNotifications([subscription]);
response.sendStatus(200);
});
- 다음 코드를 사용하여
sendNotifications()
함수를 업데이트합니다.
function sendNotifications(subscriptions) {
// TODO
// Create the notification content.
const notification = JSON.stringify({
title: "Hello, Notifications!",
options: {
body: `ID: ${Math.floor(Math.random() * 100)}`
}
});
// Customize how the push service should attempt to deliver the push message.
// And provide authentication information.
const options = {
TTL: 10000,
vapidDetails: vapidDetails
};
// Send a push message to each client specified in the subscriptions array.
subscriptions.forEach(subscription => {
const endpoint = subscription.endpoint;
const id = endpoint.substr((endpoint.length - 8), endpoint.length);
webpush.sendNotification(subscription, notification, options)
.then(result => {
console.log(`Endpoint ID: ${id}`);
console.log(`Result: ${result.statusCode}`);
})
.catch(error => {
console.log(`Endpoint ID: ${id}`);
console.log(`Error: ${error} `);
});
});
}
- 다음 코드로
/notify-all
경로 핸들러 로직을 업데이트합니다.
app.post('/notify-all', (request, response) => {
console.log('/notify-all');
response.sendStatus(200);
console.log('Notifying all subscribers');
const subscriptions =
db.get('subscriptions').cloneDeep().value();
if (subscriptions.length > 0) {
sendNotifications(subscriptions);
response.sendStatus(200);
} else {
response.sendStatus(409);
}
});
- 앱 탭으로 돌아갑니다.
- 푸시 수신 거부를 클릭한 다음 푸시 수신 신청을 다시 클릭합니다. 이는 앞서 언급한 대로 Glitch가 코드를 수정할 때마다 프로젝트를 다시 시작하고 프로젝트가 시작 시 데이터베이스를 삭제하도록 구성되어 있기 때문에 필요합니다.
- 알림 받기를 클릭합니다. 푸시 알림이 표시됩니다. 제목은
Hello, Notifications!
이고 본문은ID: <ID>
여야 합니다. 여기서<ID>
는 랜덤 숫자입니다. - 다른 브라우저나 기기에서 앱을 열고 푸시 알림을 구독한 후 모두 알림 버튼을 클릭합니다. 구독한 모든 기기에서 동일한 알림을 받아야 합니다 (즉, 푸시 알림 본문의 ID가 동일해야 함).
다음 단계
- 푸시 알림의 작동 방식을 더 깊이 이해하려면 푸시 알림 개요를 참고하세요.
- Codelab: 푸시 알림 클라이언트 빌드에서 알림 권한을 요청하고, 푸시 알림을 수신하기 위해 기기를 구독하고, 서비스 워커를 사용하여 푸시 메시지를 수신하고 메시지를 알림으로 표시하는 클라이언트를 빌드하는 방법을 알아보세요.