[java] Akka와 웹소켓의 통합

Akka는 고성능, 분산 시스템을 구축하기 위한 도구로, 메시지 기반의 액터 모델을 사용합니다. 웹소켓은 실시간 양방향 통신을 지원하는 프로토콜입니다. 이번 글에서는 Akka와 웹소켓을 연동하여 실시간 통신을 구현하는 방법에 대해 알아보겠습니다.

Akka HTTP

Akka HTTP는 Akka 기반의 웹 서버와 클라이언트를 구성하기 위한 라이브러리입니다. Akka HTTP를 사용하면 간단하게 RESTful API를 개발할 수 있습니다. 이 라이브러리를 이용하여 웹소켓을 구현할 수도 있습니다.

웹소켓 구현하기

  1. Akka HTTP의 의존성을 추가합니다. Maven을 사용한다면 pom.xml에 다음과 같이 추가합니다.
<dependencies>
  <dependency>
    <groupId>com.typesafe.akka</groupId>
    <artifactId>akka-http_2.11</artifactId>
    <version>10.0.0</version>
  </dependency>
</dependencies>
  1. 아래 코드처럼 웹소켓 핸들러를 정의합니다.
import akka.actor.AbstractActor;
import akka.http.javadsl.model.ws.Message;
import akka.http.javadsl.model.ws.TextMessage;
import akka.stream.ActorMaterializer;
import akka.stream.javadsl.Flow;

public class MyWebSocketHandler extends AbstractActor {
    private final ActorMaterializer materializer = ActorMaterializer.create(getContext());

    @Override
    public Receive createReceive() {
        return receiveBuilder()
                .match(Message.class, msg -> {
                    if (msg instanceof TextMessage) {
                        String text = ((TextMessage) msg).getStrictText();
                        // 웹소켓으로부터 받은 메시지 처리
                        System.out.println("Received message: " + text);
                    }
                })
                .build();
    }

    public Flow<Message, Message, ?> createWebSocketFlow() {
        return Flow.<Message>create()
                .map(msg -> {
                    if (msg instanceof TextMessage) {
                        String text = ((TextMessage) msg).getStrictText();
                        // 받은 메시지 가공
                        String responseText = "Processed: " + text;
                        return TextMessage.create(responseText);
                    } else {
                        throw new IllegalArgumentException("Unsupported message type");
                    }
                });
    }
}
  1. Akka HTTP 서버를 구성합니다. 아래 코드는 GET 요청을 받아 웹소켓 핸들러를 생성하는 예제입니다.
import akka.http.javadsl.Http;
import akka.http.javadsl.model.HttpRequest;
import akka.http.javadsl.model.HttpResponse;
import akka.http.javadsl.model.StatusCodes;
import akka.http.javadsl.server.Route;
import akka.http.javadsl.server.RouteResult;
import akka.http.javadsl.server.Directives;

import static akka.http.javadsl.server.PathMatchers.segment;

public class MyServer extends Directives {
    private final MyWebSocketHandler webSocketHandler = new MyWebSocketHandler();

    private Route createRoute() {
        return get(() -> path(segment("websocket"), () ->
                handleWebSocketMessages(webSocketHandler.createWebSocketFlow())));
    }

    public void start() {
        final Http http = Http.get(getContext().getSystem());
        final Route route = createRoute();
        http.bindAndHandleSync(
                asyncRequest -> {
                    RouteResult routeResult = route.createContext(asyncRequest).handle();
                    routeResult.routeResult().handle(new RouteResult.Handler<HttpResponse>() {
                        @Override
                        public void onComplete(HttpResponse httpResponse) {
                            asyncRequest.reply(httpResponse);
                        }
                    });
                },
                ConnectHttp.toHost("localhost", 8080),
                materializer);
    }
}
  1. 서버를 시작합니다.
public static void main(String[] args) {
    MyServer server = new MyServer();
    server.start();
}

결론

이렇게 Akka와 웹소켓을 통합하여 실시간 통신을 구현할 수 있습니다. Akka HTTP를 이용한 웹소켓 구현은 간단하면서도 확장성과 성능을 보장해줍니다. Akka와 웹소켓을 함께 사용하여 효율적인 분산 시스템을 구현해보세요.

참고 자료