LoginSignup
5

More than 5 years have passed since last update.

Akkaの簡単なサンプル(Java)

Last updated at Posted at 2016-06-24

簡単なAkkaのサンプルプログラムです。メッセージを送信、受信してエコーを返します。

Step1

Gradle

build.gradle
apply plugin: 'java'

repositories {
    mavenCentral()
}

dependencies {
    compile 'com.typesafe.akka:akka-actor_2.11:2.4.7'
}

Client

インスタンス生成はPropsを使用するのが流儀みたいです。
詳細は後日調べて載せます。

Client.java
package com.example;
import akka.actor.*;
import akka.event.Logging;
import akka.event.LoggingAdapter;

/**
 * クライアント
 */
public class Client extends UntypedActor {

    /** Server */
    private final ActorRef          server;

    /** ロガー */
    private final LoggingAdapter    logger;

    /**
     * アクター生成用のPropsを返す
     * 
     * @return  Props
     */
    public static Props props() {
        return Props.create(Client.class);
    }

    /**
     * コンストラクタ
     */
    public Client() {
        server = context().system().actorOf(Server.props(), "Server");
        logger = Logging.getLogger(context().system(), this);
        getSelf().tell("Start", getSelf());
    }

    /**
     * 受信処理
     */
    @Override
    public void onReceive(Object message) throws Exception {
        logger.info(message.toString());
        if (message instanceof String) {
            if (message.equals("Start")) {
                server.tell("こんにちは", getSelf());
                return;
            }
        }
        // 上記以外は処理しない
        unhandled(message);
    }

    /**
     * エントリーポイント
     * 
     * @param args  コマンドライン引数
     */
    public static void main(String[] args) {
        ActorSystem.create("Apps").actorOf(Client.props(), "Client");
    }
}

Server

Server.java
package com.example;
import akka.actor.Props;
import akka.actor.UntypedActor;
import akka.event.Logging;
import akka.event.LoggingAdapter;

/**
 * サーバ
 */
public class Server extends UntypedActor {

    /** ロガー */
    private final LoggingAdapter    logger;

    /**
     * アクター生成用のPropsを返す
     * 
     * @return  Props
     */
    public static Props props() {
        return Props.create(Server.class);
    }

    /**
     * コンストラクタ
     */
    public Server() {
        logger = Logging.getLogger(context().system(), this);
    }

    /**
     * 受信処理
     */
    @Override
    public void onReceive(Object message) throws Exception {
        logger.info(message.toString());
        if (message instanceof String) {
            getSender().tell("Echo " + (String)message, getSelf());
        }
    }

}

実行結果

[INFO] [06/24/2016 14:11:58.689] [Apps-akka.actor.default-dispatcher-2] [akka://Apps/user/Client] Start
[INFO] [06/24/2016 14:11:58.690] [Apps-akka.actor.default-dispatcher-5] [akka://Apps/user/Server] こんにちは
[INFO] [06/24/2016 14:11:58.691] [Apps-akka.actor.default-dispatcher-3] [akka://Apps/user/Client] Echo こんにちは

Step2

schedulerを使用して処理を繰り返すように修正します。
scheduleOnesは1回きりです。scheduleを使用すると繰り返し実行できます。

Client

Client.java
package com.example;
import java.util.concurrent.TimeUnit;

import akka.actor.*;
import akka.event.Logging;
import akka.event.LoggingAdapter;
import scala.concurrent.duration.Duration;

/**
 * クライアント
 */
public class Client extends UntypedActor {

    /** Server */
    private final ActorRef          server;

    /** ロガー */
    private final LoggingAdapter    logger;

    /**
     * アクター生成用のPropsを返す
     * 
     * @return  Props
     */
    public static Props props() {
        return Props.create(Client.class);
    }

    /**
     * コンストラクタ
     */
    public Client() {
        server = context().system().actorOf(Server.props(), "Server");
        logger = Logging.getLogger(context().system(), this);
        getSelf().tell("Start", getSelf());
    }

    /**
     * 受信処理
     */
    @Override
    public void onReceive(Object message) throws Exception {
        logger.info(message.toString());
        if (message instanceof String) {
            if (message.equals("Start")) {
                server.tell("こんにちは", getSelf());
                nextShedule(); 
                return;
            }
        }
        unhandled(message);
    }

    /**
     * 次処理をスケジューリングする
     */
    private void nextShedule() {
        context().system().scheduler().scheduleOnce(
                Duration.create(5, TimeUnit.SECONDS),   // delay
                getSelf(),                              // receiver
                "Start",                                // message
                context().dispatcher(),                 // executor
                getSelf()                               //sender
                );
    }

    /**
     * エントリーポイント
     * 
     * @param args  コマンドライン引数
     */
    public static void main(String[] args) {
        ActorSystem.create("Apps").actorOf(Client.props(), "Client");
    }
}

実行結果

[INFO] [06/24/2016 15:25:12.290] [Apps-akka.actor.default-dispatcher-3] [akka://Apps/user/Client] Start
[INFO] [06/24/2016 15:25:12.293] [Apps-akka.actor.default-dispatcher-4] [akka://Apps/user/Server] こんにちは
[INFO] [06/24/2016 15:25:12.293] [Apps-akka.actor.default-dispatcher-3] [akka://Apps/user/Client] Echo こんにちは
[INFO] [06/24/2016 15:25:17.312] [Apps-akka.actor.default-dispatcher-7] [akka://Apps/user/Client] Start
[INFO] [06/24/2016 15:25:17.313] [Apps-akka.actor.default-dispatcher-3] [akka://Apps/user/Server] こんにちは
[INFO] [06/24/2016 15:25:17.313] [Apps-akka.actor.default-dispatcher-7] [akka://Apps/user/Client] Echo こんにちは
[INFO] [06/24/2016 15:25:22.334] [Apps-akka.actor.default-dispatcher-2] [akka://Apps/user/Client] Start
[INFO] [06/24/2016 15:25:22.334] [Apps-akka.actor.default-dispatcher-7] [akka://Apps/user/Server] こんにちは
[INFO] [06/24/2016 15:25:22.334] [Apps-akka.actor.default-dispatcher-2] [akka://Apps/user/Client] Echo こんにちは

停止する処理を入れていないので延々処理されます。

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5