개발 기록

211222 til (웹소켓-실시간 알림 기능) 본문

TIL

211222 til (웹소켓-실시간 알림 기능)

수염차 2021. 12. 23. 03:02

로컬에서 테스트할때 WebSocketConfig 에서 프론트는 localhost:63342로 보내기때문에 이 주소도 추가해줘야 됐다 !

@Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
        registry.addEndpoint("/websocket").setAllowedOrigins("https://api.fevertime.shop", "https://www.fevertime.shop", "http://localhost:8080", "http://localhost:63342").withSockJS();
    }

 

연결 성공..!!

 

--이제 send만 하면 되는데 오류 뜸

feed.html:580 Uncaught TypeError: Cannot read properties of null (reading 'send')

에러의 원인은 스크립트 로드 우선순위가 잘못되었거나,

로드가 되지 않았거나,

스크립트가 로드될 당시 페이지에 아이디나 클래스에 해당하는 요소가 없거나 한 경우라고 한다.

 

근데 이것저것 해본 결과 메세지를 보내는 사람도 웹소켓에 연결되어있어야 send가 되는 것 같았다..

내가 웹소켓이 뭔지도 모르고 그냥 따라하려다 보니 이런 일이 생겼다..

 

그래서 원래는 댓글 달면 피드 작성자한테 알림가기 하려고 했는데 채팅방보다 이게 더 자료도 없고 까다로워보여서 같은 페이지상에서 누가 참가버튼 누르면 참가했다고 알림뜨게 했다 그냥 한번 써보는거에 의의를 둔다.. 

채팅방은 프론트까지 하면 너무 오래걸릴 것 같아서 나중에 시간 내서 해보는게 좋을 것 같다..

 

엄청 간단한건데... 암튼 했음

저 카카오아이디로 유저이름 불러오고 싶은데 그것도 안된다ㅠ

오늘 이거했넹 ..^^>................

 

피드페이지가 나은 것 같아서 피드로 바꿨다.ㅎ..


WebSocketConfig

@RequiredArgsConstructor
@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {

    private final StompHandler stompHandler; // jwt 토큰 인증 핸들러

    @Override
    public void configureMessageBroker(MessageBrokerRegistry registry) {
        registry.enableSimpleBroker("/topic");
        registry.setApplicationDestinationPrefixes("/pub");
    }

    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
        registry.addEndpoint("/websocket").setAllowedOrigins("*").withSockJS();
    }

    @Override
    public void configureClientInboundChannel(ChannelRegistration registration) {
        registration.interceptors(stompHandler);//핸들러 등록
    }
}

 

StompHandler

@RequiredArgsConstructor
@Component
public class StompHandler implements ChannelInterceptor {

    @Override
    public Message<?> preSend(Message<?> message, MessageChannel channel) {
        StompHeaderAccessor headerAccessor = StompHeaderAccessor.wrap(message);
        System.out.println("full message:" + message);
        System.out.println("auth:" + headerAccessor.getNativeHeader("Authorization"));
        System.out.println(headerAccessor.getHeader("nativeHeaders").getClass());
        if (StompCommand.CONNECT.equals(headerAccessor.getCommand())) {
            System.out.println("msg: " + "conne");
        }
        //throw new MessagingException("no permission! ");
        return message;
    }
}

 

AlarmApiController

/post로 send 하면 받은 메세지를 /topic/feed/로 보낸다

@Controller
@RequiredArgsConstructor
public class AlarmApiController {

    private final SimpMessageSendingOperations messagingTemplate;

    @MessageMapping("/post")
    public void addUser(@RequestBody MessageDto dto) {
        messagingTemplate.convertAndSend("/topic/feed", dto);
    }

}

MessageDto

@Getter
@Setter
public class MessageDto {
        private String msg;
}

 

 

 

detail.html

$(document).ready(function () {
            onSocket();
        })

        let stompClient = null;

        function onSocket() {
            let socket = new SockJS('/websocket');
            stompClient = Stomp.over(socket);
            stompClient.connect({}, function (frame) {
                console.log('Connected: ' + frame);
                stompClient.subscribe('/topic/feed', function (greeting) {
                //메세지 알람 띄우기
                    toastr.info(greeting.body.split('"')[3], {timeOut: 1000});
                });
            });
        }

		//send함수는 피드 작성시 실행됨
        function send() {
        //제일 최근에 써진 피드 가져오기
            $.ajax({
                type: "GET",
                url: "http://localhost:8080/feeds",
                contentType: 'application/json; charset=utf-8',
                success: function (response) {
                    console.log(typeof response[0]['contents'])
                    let contents = response[0]['contents']
                    let username = response[0]['username']

                    stompClient.send('/pub/post', {}, JSON.stringify({'msg': `${username}님이 피드를 작성했습니다 - ${contents} `}));
                }
            })

        }

이거 돌아가는 순서가 뭔지 잘 모르겠는데 웹소켓 connect 되고 subscribe 되고 send 되면 subscribe로 가는건지? 더 공부해야겠다..모르고 그냥 했다 그래서 시간 더 걸린듯 ㅎ.

 


 

참고자료

스프링부트 + 웹소켓 + stomp를 이용한 실시간 알림 구현

 

스프링부트 + 웹소켓 + stomp를 이용한 실시간 알림 구현

#소켓 #stomp #웹소켓 #스프링부트 #실시간알람 #실시간알림 https://kukekyakya.tistory.com/12?category&...

blog.naver.com

[Spring Boot] WebSocket과 채팅 (3) - STOMP

 

[Spring Boot] WebSocket과 채팅 (3) - STOMP

[Spring Boot] WebSocket과 채팅 (2) - SockJS [Spring Boot] WebSocket과 채팅 (1) 일전에 WebSocket(웹소켓)과 SockJS를 사용해 Spring 프레임워크 환경에서 간단한 하나의 채팅방을 구현해본 적이 있다. [Sprin..

dev-gorany.tistory.com

웹 소켓에 대해 알아보자! - 실전 편

 

웹 소켓에 대해 알아보자! - 실전 편

웹 소켓에 대해 알아보자! - 실전 편 이번 글에서는 저번에 작성했던 웹 소켓 이론 편에 이어서, 스프링 환경에서 웹 소켓을 사용하는 법에 대해 다루려고 한다. STOMP 구현하기에 앞서, 우리는 새

tecoble.techcourse.co.kr

그리고 스파르타 튜터님 깃허브

 

[Javascript] 알람 메시지 라이브러리(toastr 라이브러리)

'TIL' 카테고리의 다른 글

220106-0107 모의면접 후기  (0) 2022.01.06
211224 til (스케줄러)  (0) 2021.12.24
211221 til (Paging query & 예외처리)  (0) 2021.12.22
211217 TIL (aws ACM)  (0) 2021.12.17
211216 TIL (AWS RDS 설정)  (0) 2021.12.16
Comments