LoginSignup
3
2

More than 5 years have passed since last update.

Action CableのJavaクライアントを実装してみた

Last updated at Posted at 2016-07-26

TL;DR

Action Cable

Rails 5.0がリリースされましたが、目玉機能の一つにAction Cableがあります。

詳細はAction Cable Overviewに譲るとして、Action Cableの概要はこんな感じです。

  • RailsとWebSocketの統合を容易にするフレームワーク
  • WebSocketのサブプロトコル的なものを定義して、Pub/Subの仕組みを提供する
    • ただし、実際にはサブプロトコルとしては定義されていないようなので1socket.ioのようなものだと捉えれば良いと思います。

実は、まだ本家の開発がアルファ版だった半年以上前に、興味本位でJavaクライアントを実装していたのですが、当時は未確定な要素も多かったため、ある程度完成したところで放置していました。

今回、Rails 5.0が正式にリリースされたことを受け、せっかくなので色々整理して0.1.0としてリリースすることにしました。

紹介

GitHubのリポジトリはこちらになります。

READMEの焼き直しですが、使い方を簡単に紹介します。

Gradleによる導入

JitPack経由で、Gradleによる導入が可能です。

repositories {
    jcenter()
    maven { url "https://jitpack.io" }
}

dependencies {
    compile 'com.github.hosopy:actioncable-client-java:0.1.0'
}

基本的なインターフェース

ActionCable,Channel,Subscriptionなど、基本的にはJavaScriptのインターフェースと世界観を合わせています。
パラメータの受け渡しについては、GSONに依存することにしました2

// 1. Setup
URI uri = new URI("ws://cable.example.com");
Consumer consumer = ActionCable.createConsumer(uri);

// 2. Create subscription
Channel appearanceChannel = new Channel("AppearanceChannel");
Subscription subscription = consumer.getSubscriptions().create(appearanceChannel);

subscription
    .onConnected(new Subscription.ConnectedCallback() {
        @Override
        public void call() {
            // Called when the subscription has been successfully completed
        }
    }).onRejected(new Subscription.RejectedCallback() {
        @Override
        public void call() {
            // Called when the subscription is rejected by the server
        }
    }).onReceived(new Subscription.ReceivedCallback() {
        @Override
        public void call(JsonElement data) {
            // Called when the subscription receives data from the server
        }
    }).onDisconnected(new Subscription.DisconnectedCallback() {
        @Override
        public void call() {
            // Called when the subscription has been closed
        }
    }).onFailed(new Subscription.FailedCallback() {
        @Override
        public void call(ActionCableException e) {
            // Called when the subscription encounters any error
        }
    });

// 3. Establish connection
consumer.connect();

// 4. Perform any action
subscription.perform("away");

// 5. Perform any action using JsonObject(GSON)
JsonObject params = new JsonObject();
params.addProperty("foo", "bar");
subscription.perform("appear", params);

Channelへのパラメータ指定

先ほどの例ではChannelにパラメータを指定していませんでしたが、パラメータを指定することもできます。

Channel chatChannel = new Channel("ChatChannel");
chatChannel.addParam("room", "Best Room");
Subscription subscription = consumer.getSubscriptions().create(chatChannel);

パラメータに指定可能なデータ型としては、Number, String, Boolean,JsonElement(GSON)です。

chatChannel.addParam("room_id", 1);
chatChannel.addParam("room", "Best Room");
chatChannel.addParam("private", true);
chatChannel.addParam("params", new JsonObject());

カスタムSubscriptionの定義

基本的にメッセージの送信はSubscription#perform("action_name", params)で実行しますが、メッセージの種類に対応したメソッドを定義できたほうが便利な場合があります。

そこで、アノテーションを利用したカスタムSubscriptionの定義を行うことができます。

public interface ChatSubscription extends Subscription {
    /*
     * Equivalent:
     *   perform("join")
     */
    @Perform("join")
    void join();

    /*
     * Equivalent:
     *   perform("send_message", JsonObjectFactory.fromJson("{body: \"...\", private: true}"))
     */
    @Perform("send_message")
    void sendMessage(@Data("body") String body, @Data("private") boolean isPrivate);
}

Subscriptions#create()の第2引数に、インターフェースを指定することで、インターフェースに対応したSubscriptionを生成することが出来ます。

Channel chatChannel = new Channel("ChatChannel");
ChatSubscription subscription = consumer.getSubscriptions().create(appearanceChannel, ChatSubscription.class);

consumer.open();

subscription.join();
subscription.sendMessage("Hello", true);

Option

その他、いくつかOptionがあるのですが、長くなりそうなので詳しくはREADME#Optionsを参照して下さい。

Swift版

Javaと一緒にSwiftのクライアントも開発していたのですが、途中で面倒になった既にGitHubに公開されているものがあったため、Swift版はお蔵入りとなる予定です。。

danielrhodes/Swift-ActionCableClient

2017/09/04: Kotlin版を作りました

Kotlinの勉強ついでに...


  1. WebSocket Protocol Registries 

  2. イケてない気がするので考え直したい 

3
2
0

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
3
2