[java] Guice를 사용하여 서블릿에서 웹소켓(WebSocket) 처리하기

웹소켓(WebSocket)은 실시간 양방향 통신을 위한 프로토콜로, 클라이언트와 서버 간에 데이터를 주고받는 데 사용됩니다. Java에서는 웹소켓을 처리하기 위해 javax.websocket API를 제공합니다. 이번 포스트에서는 Guice를 사용하여 서블릿에서 웹소켓을 처리하는 방법에 대해 알아보겠습니다.

Guice 소개

Guice는 Google이 개발한 경량 의존성 주입(Dependency Injection) 프레임워크입니다. Guice를 사용하면 객체 간의 의존성을 관리하고 의존성 주입 패턴을 통해 코드를 더 유연하고 테스트 가능하게 만들 수 있습니다.

Guice를 사용한 웹소켓 처리

  1. 의존성 추가: Guice를 사용하기 위해 먼저 의존성을 추가해야 합니다. Maven을 사용한다면 pom.xml 파일에 다음 의존성을 추가합니다.

    <dependency>
      <groupId>com.google.inject</groupId>
      <artifactId>guice</artifactId>
      <version>4.2.3</version>
    </dependency>
    
  2. WebSocket 핸들러 작성: Guice를 사용하여 웹소켓 핸들러를 작성합니다. 웹소켓 핸들러는 javax.websocket.Endpoint 인터페이스를 구현해야 합니다. 다음은 간단한 예입니다.

    import javax.websocket.Endpoint;
    import javax.websocket.EndpointConfig;
    import javax.websocket.Session;
    import javax.websocket.MessageHandler;
    
    public class MyWebSocketHandler extends Endpoint {
      @Override
      public void onOpen(Session session, EndpointConfig config) {
        session.addMessageHandler(new MessageHandler.Whole<String>() {
          @Override
          public void onMessage(String message) {
            // 메시지 처리 로직 작성
          }
        });
      }
    }
    
  3. WebServlet 조정: Guice를 사용하여 웹소켓을 처리하기 위해 @WebServlet 어노테이션을 사용한 서블릿을 조정해야 합니다. Guice를 사용하여 WebSocketContainer를 인스턴스화하고 웹소켓 핸들러를 등록해야 합니다.

    import com.google.inject.Guice;
    import com.google.inject.Injector;
    import javax.websocket.server.ServerEndpointConfig;
    import javax.websocket.server.ServerContainer;
    import javax.websocket.DeploymentException;
    import javax.websocket.Endpoint;
    
    @WebServlet("/mywebsocket")
    public class MyWebSocketServlet extends HttpServlet {
      @Override
      public void init() throws ServletException {
        super.init();
        Injector injector = Guice.createInjector(new MyWebSocketModule()); // MyWebSocketModule은 Guice 모듈입니다.
        ServerContainer serverContainer = (ServerContainer) getServletContext().getAttribute("javax.websocket.server.ServerContainer");
        ServerEndpointConfig endpointConfig = ServerEndpointConfig.Builder.create(MyWebSocketHandler.class, "/mywebsocket").build();
        endpointConfig.getUserProperties().put(Injector.class.getName(), injector); // Guice 인스턴스를 등록합니다.
    
        try {
          serverContainer.addEndpoint(endpointConfig);
        } catch (DeploymentException e) {
          e.printStackTrace();
        }
      }
    }
    
  4. Guice 모듈 작성: Guice를 사용하여 웹소켓 핸들러에 의존성을 주입하기 위해 Guice 모듈을 작성해야 합니다.

    import com.google.inject.AbstractModule;
    
    public class MyWebSocketModule extends AbstractModule {
      @Override
      protected void configure() {
        // 웹소켓 핸들러에 대한 바인딩을 설정합니다.
        bind(MyWebSocketHandler.class);
      }
    }
    
  5. 웹소켓 통신: 이제 클라이언트와 서버 간에 웹소켓 통신을 할 준비가 되었습니다. 클라이언트에서 웹소켓을 연결하고 서버에서 메시지를 받을 수 있습니다.

    // 클라이언트 예시 (JavaScript)
    var socket = new WebSocket("ws://localhost:8080/mywebsocket");
    socket.onmessage = function(event) {
      var message = event.data;
      // 메시지 처리 로직 작성
    };
    

마무리

이번 포스트에서는 Guice를 사용하여 서블릿에서 웹소켓을 처리하는 방법에 대해 알아보았습니다. Guice를 통해 의존성 주입을 활용하면 코드의 유연성과 테스트 가능성을 크게 향상시킬 수 있습니다.

더 자세한 내용은 official Guice documentation을 참고하시기 바랍니다.