개발 기록
211222 til (웹소켓-실시간 알림 기능) 본문
로컬에서 테스트할때 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를 이용한 실시간 알림 구현
[Spring Boot] WebSocket과 채팅 (3) - STOMP
그리고 스파르타 튜터님 깃허브
'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 |