Shuichi Machida's Weblog

« [Sun SPOT メモ] アイソレット... | メイン | [Sun SPOT メモ] プロパティ(... »

http://blogs.sun.com/machida/date/20080328 2008年 3月 28日 金曜日

[Sun SPOT メモ] アイソレット(Isolate)間通信 (3) - Channel, ServerChannel を使う。

アイソレット(Isolate)間通信に関するメモの最後です。

Channel, ServerChannel クラスを使うと、Socket に似たインタフェースを使ってローカルのアイソレット間で通信することができます。

以下は、Sun SPOT起動時に実行されるメインのアイソレット(MIDlet)です。ここでは、子アイソレットが作成したチャネル "testchannel" を介してデータを送信しています。

package org.sunspotworld;

import com.sun.spot.util.*;
import com.sun.squawk.Isolate;
import com.sun.squawk.VM;
import com.sun.squawk.io.mailboxes.ByteArrayEnvelope;
import com.sun.squawk.io.mailboxes.Channel;
import com.sun.squawk.io.mailboxes.Envelope;
import javax.microedition.midlet.MIDlet;
import javax.microedition.midlet.MIDletStateChangeException;

public class IICTestSpot extends MIDlet {
    protected void startApp() throws MIDletStateChangeException {
        new BootloaderListener().start();   // monitor the USB (if connected) and recognize commands from host

        System.out.println("IICTestSpot: Begin." );
        try {
            Isolate isolate = new Isolate(
                    "org.sunspotworld.ChildIsolate",  // 子アイソレット
                    new String[0],
                    null, VM.getCurrentIsolate().getParentSuiteSourceURI() );


            // 子アイソレットをスタート
            isolate.start();
            
            // 子アイソレットがServerChannel で待ち受けを開始する
            // まで少し待つ(ちょっと作為的)
            Utils.sleep(2000L);
            
            // 子アイソレットが作成したサーバチャネル "testchannel"
            // を検索する
            Channel channel = Channel.lookup("testchannel" );
            
            // 子アイソレットに渡すデータを用意して "Envelope" に封入
            byte[] message = "Hello Duke!".getBytes();
            Envelope mail = new ByteArrayEnvelope(message);

            
            // チャネルを通して "Envelope" を送信
            channel.send(mail);
            
            // 子アイソレットが終了するまで待機
            isolate.join();
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        System.out.println("IICTestSpot: End." );
        
        while (true) {
            Utils.sleep(2000L);
        }
    }
    
    protected void pauseApp() {
    }
    
    protected void destroyApp(boolean arg0) throws MIDletStateChangeException {
    }
}

子アイソレットでは、サーバチャネルを生成してクライアントからの接続を待機します。接続したら、データを受け取って表示します。

package org.sunspotworld;

import com.sun.squawk.io.mailboxes.Channel;
import com.sun.squawk.io.mailboxes.Envelope;
import com.sun.squawk.io.mailboxes.MailboxInUseException;
import com.sun.squawk.io.mailboxes.ServerChannel;

public class ChildIsolate {
    public static void main(String[] args) {
        System.out.println("ChildIsolate: Begin." );
        
        // 子スレッドを生成し、終了まで待機
        Thread server = new Server();
        server.start();
        try {
            server.join();
        } catch (InterruptedException ignored) {}
        System.out.println("ChildIsolate: End." );
    }
    
    static class Server extends Thread {
        public void run() {
            ServerChannel serverChannel = null;
            Channel channel = null;

            try {
                // サーバチャネルを生成
                serverChannel = ServerChannel.create("testchannel" );
            } catch (MailboxInUseException ex) {
                throw new RuntimeException(ex.getMessage());
            }
            
            try {
                // クライアントが接続するまで待機
                channel = serverChannel.accept();
                
                // "Envelope" を受信
                Envelope mail = channel.receive();
                
                // コンテンツを取得して表示
                byte[] message = (byte[])mail.getContents();
                System.out.println("Got a message: " + new String(message));
            } catch (Exception ex) {
                ex.printStackTrace();
            } finally {
                if (channel != null) {
                    channel.close();
                }
                serverChannel.close();
            }
        }
    }
}

アプリケーションを配備後、NetBeans IDE から起動すると、、

# NetBeans IDE の出力ウィンドウ

アイソレット間通信に成功しました!

main への引数、プロパティと比較しても柔軟性が高く、いろいろ使えそうです。

投稿されたコメント:

コメント
  • HTML文法 不許可

Valid HTML! Valid CSS!

This is a personal weblog, I do not speak for my employer.