작성
·
104
1
안녕하세요, 일단 양질의 강의를 올려주셔서 감사하다는 말씀을 드립니다.다름이 아니라, 화면을 그리지 않고 단순히 백엔드 소스를 구현하면서 강의를 진행하고있습니다.https://jiangxy.github.io/websocket-debug-tool/라는 사이트에서 Connect(STOMP), pub/sub을 테스트 중입니다.그 과정에서 DISCONNECT를 진행할 경우, 아래와 같은 에러 메세지가 발생합니다.
ava.lang.IllegalStateException: Message will not be sent because the WebSocket session has been closed
at org.apache.tomcat.websocket.WsRemoteEndpointImplBase.writeMessagePart(WsRemoteEndpointImplBase.java:455)
at org.apache.tomcat.websocket.WsRemoteEndpointImplBase.sendMessageBlockInternal(WsRemoteEndpointImplBase.java:313)
at org.apache.tomcat.websocket.WsRemoteEndpointImplBase.sendMessageBlock(WsRemoteEndpointImplBase.java:266)
at org.apache.tomcat.websocket.WsRemoteEndpointImplBase.sendMessageBlock(WsRemoteEndpointImplBase.java:250)
at org.apache.tomcat.websocket.WsRemoteEndpointImplBase.sendPartialString(WsRemoteEndpointImplBase.java:223)
at org.apache.tomcat.websocket.WsRemoteEndpointBasic.sendText(WsRemoteEndpointBasic.java:48)
at org.springframework.web.socket.adapter.standard.StandardWebSocketSession.sendTextMessage(StandardWebSocketSession.java:217)
at org.springframework.web.socket.adapter.AbstractWebSocketSession.sendMessage(AbstractWebSocketSession.java:108)
at org.springframework.web.socket.handler.ConcurrentWebSocketSessionDecorator.tryFlushMessageBuffer(ConcurrentWebSocketSessionDecorator.java:190)
at org.springframework.web.socket.handler.ConcurrentWebSocketSessionDecorator.sendMessage(ConcurrentWebSocketSessionDecorator.java:163)
at org.springframework.web.socket.messaging.StompSubProtocolHandler.sendToClient(StompSubProtocolHandler.java:529)
at org.springframework.web.socket.messaging.StompSubProtocolHandler.handleMessageToClient(StompSubProtocolHandler.java:516)
at org.springframework.web.socket.messaging.SubProtocolWebSocketHandler.handleMessage(SubProtocolWebSocketHandler.java:386)
at org.springframework.messaging.support.ExecutorSubscribableChannel$SendTask.run(ExecutorSubscribableChannel.java:152)
at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54)
at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:572)
at java.base/java.util.concurrent.FutureTask.run$$$capture(FutureTask.java:317)
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java)
at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:304)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642)
at java.base/java.lang.Thread.run(Thread.java:1583)
해당 문제를 해결하기 위해, 관련해서 자료를 검색해보았지만 해결하지 못해 질문을 드립니다.
혹시 확인을 해보아야할 메소드나 검색 키워드를 알려주실 수 있을까요?
이미지도 첨부드립니다.
답변 3
0
0
안녕하세요~ 일단 강의열심히 들어주셔서 감사한 마음을 전합니다.
보내주신 에러는 이미 세션이 끊겼을때 disconnect요청을 보내서 나오는 에러로 보입니다.
스프링은 클라이언트에서 일정시간동안 요청이 없으면 알아서 세션을 끊어 버리는데, 혹시, 매번 테스트할때마다 disconnect에서 에러가 나는걸까요? 아니면 특정 시간이 지난후에 테스트 해보신걸까요?
0
안녕하세요, 인프런 AI 인턴입니다. John님.
DISCONNECT 이벤트 시 발생하는 “Message will not be sent because the WebSocket session has been closed” 라는 오류는 주로 WebSocket 연결이 정상적으로 종료되지 않거나, 이미 종료된 WebSocket 세션으로 메시지를 전송하려고 할 때 발생합니다. 이 문제를 해결하기 위해서는 몇 가지 점검사항이 필요합니다.
WebSocket 연결 상태 확인: 메서드에서 WebSocket 세션이 여전히 연결되어 있는지 확인하는 조건문을 추가합니다. 메시지를 전송하기 전에 session.isOpen()
등을 통해 세션이 열려있는지 확인하세요.
정확한 DISCONNECT 처리: 클라이언트가 DISCONNECT 요청을 보낼 때, 서버가 이를 잘 받아들이고 세션을 정상 종료하는지 확인합니다. 서버는 DISCONNECT 메시지를 받아 세션을 정상적으로 종료하고 메모리를 적절히 해제해야 합니다.
예외 처리: 예외가 발생할 수 있는 부분에 try-catch 블록을 두어 예외 발생 시 이를 처리하고, 연결을 안전하게 종료하도록 만듭니다.
세션 관리 최적화: 세션 개별 관리를 통해, 각 세션의 상태 변화를 잘 감지하고 적절히 반응하도록 합니다. 서버 측에서 연결된 WebSocket 세션을 리스트로 관리하면서 특정 클라이언트가 연결해제 요청을 보낼 때 목록에서 제거합니다.
추가로, 비슷한 문제를 다룬 URL을 참고하여 문제해결에 도움을 받을 수 있습니다:
- Spring WebSocket Session Handling - 웹소켓 세션 관리 및 에러 처리 방법
문제가 해결되지 않거나 추가적인 정보가 필요하시다면 질문을 이어가 주세요. 관련 사항에 대해 지식공유자가 더욱 심도 있는 답변을 제공할 수 있을 것입니다.
저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다.
현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏 추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.
일단, 프론트를 외부 사이트를 활용해서 테스트 하다보니 제가 봐드릴수 있는 부분이 제한적입니다ㅜ
백엔드 파트만 진행하시더라도, 차라리 프론트엔드 코드를 clone받으셔서 local에서 실행시켜놓고 테스트 해보심이 어떨까요?