-
[React] 웹 푸시 사용해 보기 (1)개인공부 2025. 3. 20. 10:37
React로 간단한 웹 앱을 제작 중이었는데 알림이 필요하게 되었습니다.
어플로 만들기에는 너무 간단한 기능이라 앱 설치가 귀찮을 거 같아서 그냥 웹 푸시로 진행하기로 했어요.
현재 express로 react 클라이언트랑 통신중이었기 때문에 해당 서버에 웹 푸시 기능까지 추가하겠습니다.
npm install web-push -g
web-push 전역으로 패키지 설치(빼고 하면 환경변수 지정해야 합니다.)
# node js
const express = require('express'); const path = require('path'); const cors = require('cors'); const WebSocket = require('ws'); const webPush = require("web-push"); const connected_clients = {} const vapidKeys = { publicKey: "공개키", privateKey: "비밀키" }; webPush.setVapidDetails( "mailto:이메일@적어주면.됩니다", vapidKeys.publicKey, vapidKeys.privateKey );
우선 서버에서 연결할 클라이언트 connected_clients 로 저장하고 웹 푸시 패키지 가져옵니다.
웹 푸시 패키지에서는 서버랑 클라이언트가 서로 브라우저 통해서 알림을 주고 받을 수 있게 인증키를 생성하는 역할도 합니다. 해당 인증키 vapidkeys로 저장합니다.
해당 인증키는
web-push generate-vapid-keys
를 CMD에 입력해서 생성할 수 있어요. 패키지 전역으로 설치했기 때문에 web-push 로 바로 수행할 수 있습니다.
VAPID(Voluntary Application Server Identification) 는 특정 서버만이 어플리케이션에 알림을 줄 수 있도록 인증하는 역할을 하는데 가로채이면 아무나 해당 클라이언트에 알림(광고나 이상한 이미지 등)을 줄 수 있습니다.
따라서 비밀키는 코드 말고 환경변수나 다른 내부 저장소에 저장하면 좋다고 합니다.
저는 테스트용이기도 하고 그냥 코드에 적었는데 재발급 받으면 기존 vapid는 사라져서 클라이언트, 서버 모두 키를 수정해야 하니 다른 곳에 저장하면 좋습니다.
현재 작성중인 서버는 로그인 시 클라이언트와 웹소켓으로 연결시키고 있어서, 메시지 같은 경우에는 그냥 보내도 되지만 창을 최소화 하거나 탭을 전환하여도 알림이 가게끔 하는게 목표라 웹 푸시를 사용합니다.
1. 웹 푸시
우선 웹 푸시 기능을 위해선 브라우저 또는 안드로이드나 IOS에서 알림 요청을 수락하여야 합니다. 해당 요청을 Subscription으로 보통 브라우저가 보내는데 알림 서비스를 구독한다는 개념으로 이해하면 편합니다.
서버가 알림 서비스를 제공할건데 해당 서비스를 클라이언트가 받겠다고 말하는 거죠.
subscription 객체에는 브라우저 endpoint나 만료시간, 위에서 생성한 Vapid 키가 들어갑니다.
즉, 서버에서 저 알림 요청을 수락하는 과정(구독)이 필요합니다.
언제 클라이언트에서 구독을 전송해야하나 고민하다가.. 그냥 유저가 권한을 수락할때까지 계속 확인하고, 수락하면 구독을 보내기로 했습니다. 물론 거절하는 경우에도 권한 확인은 멈추게 작성합니다.
이제 클라이언트 별 구독 정보를 저장합니다.
app.post("/subscribe", (req, res) => { const { userID, subscription } = req.body; console.log('클라이언트에서 subscription 요청',req.body) const key = String(userID); if (!subscription) { console.log('유효하지 않은 구독 정보') return res.status(400).json({ error: "유효하지 않은 구독 정보" }); } subscriptions[key] = subscription; res.status(200).json({ message: "subscription 전송 완료"}); console.log('구독 정보 확인',subscriptions) });
클라이언트에서 권한을 수락해서 notification이 granted가 되면 해당 API 요청을 보냅니다.
클라이언트 식별 ID, 구독 정보를 받으면 해당 접속 정보를 서버가 저장합니다.
엣지나 크롬에서 해당 notification 세팅은 아래 주소 입력 후 확인할 수 있습니다.
chrome://settings/content/notifications
edge://settings/content/notifications
껐다 키시면서 테스트 하시면 되는데 혹시 브라우저 세팅을 일일이 초기화 하기 귀찮다면 시크릿 모드를 사용해 테스트 하면 해당 정보 초기화 됩니다.
이제 서버에서 원할 때, 식별 클라이언트 ID, 구독 정보를 이용해 알림을 줄 수 있습니다.
식별 ID도 구독에 브라우저 endpoint가 들어있어 안보내도 될 거 같은데 저는 클라이언트에서 사용하는 부분이 있어 같이 보냅니다.
//서버에서 원할때 const subscription = subscriptions[userID]; const payload = JSON.stringify({ title: "알림 도착착", body: "대기열이 업데이트되었습니다!", }); webPush.sendNotification(subscription, payload) .then(() => console.log(`${userID}에게 알림 완료!`)) .catch(err => console.error(`${userID}에게 알림 실패!`, err));
서버에서 원하는 타이밍에 위 코드로 알림을 발송합니다.
이제 웹 푸시를 위해서는 프로젝트 폴더에 서비스워커 파일을 작성해야 하고, 크롬도 되는 지 확인해야 하는데 이 내용은 다음 포스팅에 정리하겠습니다.
'개인공부' 카테고리의 다른 글
[React] 웹 푸시 사용해 보기 (2) (0) 2025.03.25 [RN] BLE 연결 및 통신 (0) 2024.08.22 Docker 로 앱 서버 연결해두기 (0) 2024.07.30 react 로컬 DB에서 데이터 가져오기 (0) 2024.07.12