티스토리 뷰

TextWebSocketHandler를 이용하여 웹소켓을 구현하였다면 구현체 내부에선 직접적으로 HttpSession 접근이 불가능하다. 이를 해결하기 위해선 HttpSession 핸드쉐이킹 과정이 필요하다.


1. HttpSessionInterceptor 구현

import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.http.server.ServletServerHttpRequest;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.WebSocketHandler;
import org.springframework.web.socket.server.support.HttpSessionHandshakeInterceptor;

import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpSession;
import java.util.Map;

@Component
public class HttpSessionInterceptor extends HttpSessionHandshakeInterceptor {

  @Override
  public boolean beforeHandshake(ServerHttpRequest request, 
    ServerHttpResponse response, WebSocketHandler wsHandler, 
    Map<String, Object> attributes) throws Exception {
    
    // 웹소켓 경로에만 적용
    if (request.getURI().toString().contains("/ws/")) { 
      HttpSession session = getSession(request);
      if (session != null) {
        attributes.put("httpSession", session);
      }
    }
    
    return super.beforeHandshake(request, response, wsHandler, attributes);
  }

  private HttpSession getSession(ServerHttpRequest request) {
    if (request instanceof ServletServerHttpRequest) {
      HttpServletRequest servletRequest = 
        ((ServletServerHttpRequest) request).getServletRequest();
        
      return servletRequest.getSession(false);
    }
    return null;
  }
}
  • HttpSessionHandshakeInterceptor 상속받아 웹소켓 경로로 request 요청이 유입했을 때, 해상 request 정보를 session에 저장하는 작업이 필요하다.

 

2. WebSocketHandler 구현

@Component
public class WEbSocketHandler extends TextWebSocketHandler {

  // 연결(클라이언트 접속)
  @Override
  public void afterConnectionEstablished(WebSocketSession session) throws Exception {

	String userId = "";
    
    try {
      HttpSession httpSession = (HttpSession) session.getAttributes().get("httpSession");
      userId = ((UserVO)httpSession.getAttribute(SessionKeys.USER_VO.name())).
		getLginData().getUserId();
    }catch (Exception e){

    }

    System.out.println("클라이언트 접속 : [ " + userId + " ]");
  }

  ... 생략

}



감사합니다.

최근에 올라온 글
Total
Today
Yesterday