[스프링 웹소켓] 스프링웹소켓과 sockjs로 실시간 알림 만들어보자

2024. 8. 1. 12:32카테고리 없음

pom.xml에 등록해주고 메이븐 업데이트해줍시다

 

 

]

서블릿콘텍스트에 빈등록 및 핸들러 매핑해줍시다 path는 핸들러의 경로랑 sockjs경로랑 일치하게 해줬습니다

HttpSessionHandshakeInterceptor는 확실하지는 않은데

웹소켓 세션이랑 HttpSession이랑 악수하면서 연결해주는거고 웹소켓세션에 있는 값을 HttpSession으로 불러올수 있는 그런걸로 알고있습니다

 

 

이거 핸들러구요 풀코드입니다 jsp 보여드린담에 설명드릴게요

TextWebSocketHandler를  상속받아서 

afterConnectionEstablished, (연결되면)

handleTextMessage, (메세지오면)

afterConnectionClosed (연결끊기면)를 상속받아주면 됩니다

 

 

 

<script src="https://cdn.jsdelivr.net/npm/sockjs-client@1/dist/sockjs.min.js"></script>

이게 sockjs cdn입니다

 

 

alarmSocket = new SockJS("http://localhost/alarm");

이렇게 jsp에 선언해주시구요 

 

뒤에 alarm 이거는 서블릿콘텍스트, 핸들러랑 맞췄습니다

 

 

onopen은 소켓에 연결되었을때,

onmessage는 메세지를 받았을때,

onclose는 소켓 끊겼을때 호출되는 메소드입니다`

 

 

이부분은 알림을 핸들러로 보내는 메소드인데요 파라미터는 본인이 알아서 뭐보내고싶은지 정해서 핸들러로 보내면 됩니다~

changeAlarmType 보시고 불편하실텐데 그냥 JSON.stringify 하면 편합니다 근데 저거 처음에 공부할땐 저렇게 했었어요..

 

 

 

그러면 이제 알림을 보내는 이벤트(예를들면 수정, 삭제 등등)에 sendAlarm 메소드를 파라미터 넣어서  같이 호출해주면 되는겁니다!

 

호출해주면 Handler의 handleTextMessage로 이동하는데요 

 

이게 초반부분입니다

파라미터로 세션과 메세지가 있는데 

getPayload()를 이용해서 값을 받아온 다음에

json오브젝트로 바꾼 다음

 

스트링값으로 바꿔줍니다

 

 

 

 

제가 파라미터로 보낸 type에 따라서 if문으로 섹션을 나눴습니다 updateStatus는 상태변경이죠

상태가 변경될때는 저쪽을 타는겁니다 

armCategoryNo는 알람 카테고리번호라 깊게 생각하지 않으셔도 됩니다.

 

파라미터로 보낸 value에 1,2,3,4를 넣어서 보냈는데 상태값이랑 매핑해주고요

alarm 테이블 = 알림의 내용 저장

alarmTo 테이블 = 알림번호와 알림을 받을 사람 저장했습니다

 

alarm 테이블에 먼저 값을 입력해주었고

managerList는 알림을 받을 녀석들의 기본키를 담은녀석입니다

for문 돌려서 알림을 받을 녀석들도 alarmTo 테이블에 입력해줍니다

 

그다음에 웹소켓에 실제로 알림을 실시간으로 받을 사람들을 걸러줍니다 !!

 

 

위 사진의 아래부분 바로 이부분인데요 

 

alarmMap이 어디서나왔느냐 보면 

 

핸들러 시작부분에 WebSocketSession이 key값인 녀석으로 전역변수 설정이 되어있습니다 !

 

암튼 그 위 사진을 설명하자면

웹소켓 세션에 있는(현재 접속해있는) 모두의 수만큼 반복문을 돌려서

웹소켓세션에서 empInfo로 미리 저장해놓았던 사원정보를 불러오고

그다음 비교하는겁니다

 

ProNoList는 해당 사원이 속해 있는 프로젝트 리스트입니다

그녀석의 사이즈만큼 반복문을 다시 돌린다음에 

알림이 발생한 프로젝트번호(sendAlarm에서 proNo로 파라미터 줬습니다)와 현재 접속해있는 사원이 속한 프로젝트의 번호와

일치하면 그사람에게 sendMessage 처리를 하는겁니다 !

 

 

 

 

핸들러에서 sendMessage 를 하면

jsp에서 alarm.onmessage 메소드로 값이 오겟죠? 

 

 

그 부분이 이부분인데요 변경된 내용에 대한건 db에다가 집어넣어놨으니

알림이 왔다라는 표시만 해주고 알림 아이콘을 클릭했을때 db에서 값을 빼올겁니다

 

일단 알림이 왔다 표시는 viewRed로 썼는데요 저 html에 빨간점입니다

저 데이터를 넘겨서 세션에 담아주는겁니다! 왜그러냐면 

저 빨간점을 넣어놓아도 세션에 없으니 새로고침이나 페이지가 이동되면 빨간점이 사라지기 때문이죠

 

 

세션에 넣어주기 성공~

 

여기가 그 빨간점 타겟인 alarmToggleDropdownIcon인데요

코어태그를 이용해서 alarmHtml이라는 세션이 비어있지 않으면 아까 넘긴 뱃지 html을 출력해주는겁니다

 

그럼 페이지가 이동되어도 문제없습니다

 

그다음에 부모요소인 a태그를 클릭하면 showMyAlarm 메소드가 실행되게끔 해놓았는데요

 

이게 showMyAlarm입니다

 

 

근데 여기 데이터를 안넘겼는데 내건지 어떻게 알아요? 하면 컨트롤러에서 세션에 있는 값 받아왔습니다

alarmList를 불러와서 핸들러에서 설정해준 armCategoryNo에 따라 바꿔주고요

 

그녀석을 드롭다운에 넣어줍니다

 

그 아래 changeYN은 그냥 읽음처리 해주는거구요

그 아래 removeRed.do는 세션에 등록된 그 빨간 점을 삭제해줍니다

 

근데 한번에 하면 되는데 한개씩 추가하고 생각없이 하면서 이렇게 아작스가 많아졌네요

불편하게해드려서 죄송합니다 

 

 

이런식으로 구현해봤습니다