• Vue Web Socket 실시간 알림

    2022. 2. 21.

    by. 순일

     

    Spring Boot Web Socket 실시간 알림

     프로젝트로 SNS를 개발하던 도중 실시간 알림 기능이 필요하게 되어 구글링을 통해 알아보던 중 좋은 블로그를 접하게 되었고 해당 블로그를 참고하여 개발을 성공할 수 있었다.  먼저 웹은 HTT

    soonil.tistory.com

    해당 포스팅에 이어 이번에는 Vue 코드도 설명과 함께 포스팅하도록 하겠다.

     

    참고 블로그 : https://velog.io/@skyepodium/vue-spring-boot-stomp-%EC%9B%B9%EC%86%8C%EC%BC%93

     

    먼저 코드 설명 전에 npm을 통해 라이브러리를 설치해주어야 한다.

    npm i webstomp-client sockjs-client

     

     프로젝트 주제가 SNS였기 때문에 팔로우 신청을 예시로 코드를 보여주고 설명할 예정이며, Vuex store를 이용했기 때문에 Vuex에 맞춰 설명하도록 하겠다. 아래 두 코드 모두 store의 actions에 작성해서 사용했으며, 메인 페이지가 created 될 때 connect()를 호출해 주었고, 팔로우를 신청할 경우 follow를 호출하도록 하였다. msg를 Object 형으로 전송함으로써 서버 측 Controller에서 Dto로 데이터를 가져올 수 있었다.

     

    1. connect => WebSocket를 연결하는 부분

        connect() { // 웹 소켓 연결하는 부분.
          const serverURL = "http://localhost:5500";
          let socket = new SockJS(serverURL);
          this.stompClient = Stomp.over(socket);
          console.log(`소켓 연결을 시도합니다. 서버 주소: ${serverURL}`);
          this.stompClient.connect(
            {},
            (frame) => {
              // 소켓 연결 성공
              this.connected = true;
              console.log("소켓 연결 성공",frame);
              // 서버의 메시지 전송 endpoint를 구독합니다.
              // 이런형태를 pub sub 구조라고 합니다.
              this.stompClient.subscribe(`/alarm/receive/${this.state.userInfo.no}`, (res) => {
                this.dispatch('alarmselect') //해당 부분에서 store에 있는 alarmselect를 호출 -> 디비에 저장된 읽지 않은 알림을 다가져와줌
                const obj = JSON.parse(res.body); //여기에 전송받은 데이터가 저장되어있음
                if(obj.type === 1){
                  console.log("팔로우 신청 도착")
                }
              });
            },
            (error) => {
              // 소켓 연결 실패
              console.log("소켓 연결 실패", error);
              this.connected = false;
              this.state.socketcount++
              if(this.state.socketcount > 10){ //소켓 연결 실패 시 재귀를 통해 반복하고 10회이상 카운트 하면 로그아웃 시킴
                const authInst = window.gapi.auth2.getAuthInstance();
                console.log('signout called', authInst)
                authInst.signOut()
                .then(() => {
                  // eslint-disable-next-line
                  console.log('User Signed Out!!!');
                  authInst.disconnect();
                  session.clear();
                })
                .then(() => {
                  window.location.reload()
                })
                .catch(() => alert('fail'))
                alert("서버 문제 발생")
              }
              this.dispatch('connect'); // 소켓 재연결 시도
            }
          );
        },

     

    2. follow => WebSocket으로 팔로우 정보 날려주는 부분 

         follow(state, el) { //팔로우 알림 보내는 부분 파라미터로 받는사람 유저번호 넘겨줌
          console.log("팔로우 알림");
          if (this.stompClient && this.stompClient.connected) {
            const msg = {
              sender: this.state.userInfo.no,
              receiver: el,
              type: 1, 
            };
            this.stompClient.send(
              "/alarm/send/" + el,
              JSON.stringify(msg),
              {}
            );
          }
        },
    728x90

    댓글