프론트 sse를 통한 알림기능 구현

위범석·2022년 9월 2일
1

sse를 통해 알림 기능구현에 앞서,

프론트가 해야하는 것들을 정리한 다음에 작업에 들어 가야할거 같다.

현재 테스트로 완성된 것들

  1. 실시간으로 데이터를 받아와서 나타내기

  2. 프론트에서 구독할때 header에 토큰 담아서 보내기

이 테스트를 기반으로 우리 페이지에서 나타낼려고 하는건

유저가 채팅을 입력 하면 상대방의 홈 화면에서 알림이 가는데, 카카오톡 처럼 안읽었다는 기록을

남기고 싶어서 기능 구현을 들어가게 되었다.

프론트가 해야할것.

  1. 로그인을 했을때 구독신청

  2. 구독이된 유저한테 백에서 data가 오게 되면, data를 토대로 알림 안읽음 나타내기

  3. 만약 유저가 알림창을 누르면 안읽었다는 ui가 사라지고 어떤사람이 채팅을 보냈는지 백에서
    보내준 data를 토대로 나타내기.

지금 문제는 알림창을 눌렀을때 안읽음 ui는 사라지나 기록이 되질 않아서 새로고침을 하면 다시

안읽음 ui가 보이게 되는것이다. 로컬스토리지에 기록을 저장하는데 백에서 데이터가 오면,

안읽음을 나타내고 로컬에 저장, 클릭을 하게되면 읽음으로 바꾸고 로컬에 저장

일단 이런식으로 생각하고 있는데 구현이 될 지 잘 모르겠다..

##################

sse 구현 완료!! 백에서 로그인 했을때의 구독이 유지가 안되고 토큰인식도 백에서 되지 않아서,

url에 redux store에 있는 email값을 같이 보내서 인식 시키는 방법을 선택하기로 했당...

결국 데이터를 받아와서 성공 !!

웹에서의 알림... 자료가 많이 없어서 힘들었지만 그래도 단방향 + 구독과 함께 프론트의 이벤트

전달없이 백에서의 전달만으로 자료를 받는게 정말 신기한거 같다.

나는 여태까지 render링이 있을때 client가 서버에 데이터를 보내야만 프로그램을 짤 수 있는 줄

알았는데 다른 방식도 알게 되어서 너무 신기하다 유튜브에도 알람기능을 보았었는데 그렇게 큰 사

이트에서는 어떤 기술을 사용하는지 많이 궁금해졌다!!..

생각 보다 코드가 길지 않아서 놀랬다 구독을 한 후에 ui만 나타내는 작업을 하였다.

#알람 코드


import React, { useState, useEffect } from "react";

// css
import "./Toast.css";



function ToastNotification(props) {

    function toastClickEvent(props) {
        props.setToastState(false);
    }
    useEffect(() => {
        var timer2;
        let timer = setTimeout(() => {
            props.setToastAnimation("toast-alert openAnimation");
            timer2 = setTimeout(()=>{
                props.setToastState(false);
            },500);
        }, 3000);
        return () => {
            props.setToastAnimation("toast-alert closeAnimation");
            clearTimeout(timer);
            clearTimeout(timer2); }
    }, []);

    return (
        <div className={props.toastAnimation} onClick={()=>{toastClickEvent()}}>
            <img alt="" src="/images/alert2.png" />
            <p style={{fontFamily: 'GamjaFlower-Regular'}}>알림이 도착하였습니다!</p>
        </div>
    );
}

export { ToastNotification }

알람 css

.toast-alert {
    z-index: 7;
    background-color: rgba(255, 127, 80, 0.7);
    border: 1px solid rgba(255, 127, 80, 0.1);
    border-radius: 10px;
    box-shadow: 0 0.5rem 1rem rgb(0 0 0 / 80%);
    height: 40px;
    width: 300px;
    padding: 5px;
    text-align: center;
    font-size: 1.5rem;
    font-weight: bold;
    color: black;
    display: flex;
    align-items: center;
    justify-content: center;
    position: fixed;
    top: 3%;
    left: 36%;
}

.toast-alert img {
    width: 50px;
    height: auto;
    margin-right: 10px;
}

.toast-alert p {
    margin: 0;
}
@keyframes slideIn {
    from {
        transform: translateY(0%);
    }
    to {
        transform: translateY(-300%);
    }
}

@keyframes slideOut {
    from {
        transform: translateY(-300%);
    }
    to {
        transform: translateY(0%);
    }
}

.openAnimation {
    animation: slideIn 0.5s ease-in-out 0s 1 normal forwards;
}

.closeAnimation {
    animation: slideOut 0.5s ease-in-out 0s 1 normal forwards;
}
profile
코린이

0개의 댓글