코딩마을방범대

서버에서 웹소켓 세션 종료하기 본문

💡 백엔드/Java

서버에서 웹소켓 세션 종료하기

신짱구 5세 2023. 11. 20. 17:01

 

 

 

클라이언트에서 웹소켓 연결을 해제하기 어려운 경우 부득이하게 서버에서 종료를 해줘야하는 경우가 있다.

서버에서 해제하는 방법은 추천되지 않는다고 하나, 어쩔 수 없는 경우엔 사용할 수 밖에 없다..

 

HandshakeInterceptor나 WebSocketMessageBrokerConfigurer 등을 통해 웹소켓 수발신 세팅이 완료되어 있다는 전제 하에 서버에서 웹소켓 연결을 끊는 로직을 구성해볼 것이다.

 

웹 소켓을 이용한 메시지 전송(백엔드 - SpringBoot)

웹 소켓을 이용한 메시지 전송(클라이언트) WebSocket 웹버전의 TCP 또는 Socket 서버와 클라이언트 간에 Socket Connection을 유지해서 언제든 양방향 통신 또는 데이터 전송이 가능하도록 하는 기술 Real-t

sweet-rain-kim.tistory.com

 

 

 

 


 

 

 

 

 

 

 

나는 웹소켓 연결 후 30초 이후에 세션 연결을 해제하는 것으로 구성했다.

클라이언트 측에 웹소켓 연결 해제 로직이 구성되어 있다면 연결 해제를 두 번 호출하는 등의 문제가 있지만,

그렇다고 오류가 발생하진 않는 것으로 확인됐다.

 

 

EventListener의 connectedWebsocketHandler 메소드에서 타이머를 설정해주었다.

 

챗GPT에 검색해서 여러 방법을 사용해봤는데 계속 Session이 null이거나 User가 null 이였다..

아래 방법으로 하니 정상적으로 웹소켓 연결이 해제되었다.

 

 

 

 


 

 

사용하기

 

EventListener의 connectedWebsocketHandler 메소드

 

아래 로직은 30초 이후에 타이머가 작동하여 SessionDisconnect 이벤트를 발생시키는 로직이다.

뭔가 전문성 있는 코드가 아니라 대충 끼워넣은 코드같아서 찝찝하긴 한데 다른 방법이 떠오르지 않아서 어쩔 수 없다...ㅜㅠ

 

@EventListener
public void connectedWebsocketHandler(SessionConnectedEvent sessionConnectedEvent) {
	MessageHeaderAccessor messageHeaderAccessor = NativeMessageHeaderAccessor.getAccessor(sessionConnectedEvent.getMessage(), SimpMessageHeaderAccessor.class);
	GenericMessage generic = (GenericMessage) messageHeaderAccessor.getHeader("simpConnectMessage");
	Map<String, String> simpSessionAttributes = (Map<String, String>) generic.getHeaders().get("simpSessionAttributes");
	StompHeaderAccessor headerAccessor = StompHeaderAccessor.wrap(sessionConnectedEvent.getMessage());
	...
	disconnectSession(headerAccessor.getSessionId());
}

public void disconnectSession(String sessionId){
	Timer timer = new Timer();
	timer.schedule(new TimerTask() {
		@Override
		public void run() {
			StompHeaderAccessor headerAccessor = StompHeaderAccessor.create(StompCommand.DISCONNECT);
			headerAccessor.setSessionId(sessionId);
			Message<byte[]> message = MessageBuilder.createMessage(new byte[0], headerAccessor.getMessageHeaders());
			SessionDisconnectEvent event = new SessionDisconnectEvent(this, message, sessionId, CloseStatus.NORMAL);
			eventPublisher.publishEvent(event);
		}
	}, 30000);
}

 

 

 

 

SMALL