Shuichi Machida's Weblog

« [Sun SPOT Demo(4)]... | メイン | [Sun SPOT でJukeBoxを作... »

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

[Sun SPOT Demo(5)] Socket Proxy: Webにアクセスしてみる。

Sun SPOT上のプログラムから、インターネットのWebサービスにアクセスすることができます。今回は、Sun SPOTの機能の一つである Socket Proxy を使ったWebアクセスの方法についてご紹介します。

# Webアクセスの概念図。Sun SPOTからは直接インターネットに接続することができないため、ホストPC上で動作する Socket Proxy を介してアクセスします。

まず、Socket Proxy を起動します。ベースステーションをホストPCにつなぎ、Sun SPOT SDK のホームディレクトリ(例えば c:\Program Files\Sun\SunSPOT\sdk)で以下のコマンドを実行します。

 ant socket-proxy-gui

( GUIを表示しない場合は ant socket-proxy)

実行すると、以下のようなウィンドウが表示されます。


 「Start」ボタンをクリックします。デフォルトでは、Radiogram ポート10番で ProxyServerが起動し、Sun SPOTからのコネクション待ち受けを開始します。

次に、Sun SPOTアプリケーションを作成します。今回は、java.net のサイトからトップのWebページを取得して System.out に表示し、HTTPレスポンスのステータスがOKの場合は青色、それ以外は赤色でLEDを点滅させる、という単純なプログラムを作成します。

# MIDlet

package org.sunspotworld.demo.http;

import com.sun.spot.sensorboard.EDemoBoard;
import com.sun.spot.sensorboard.peripheral.ITriColorLED;
import com.sun.spot.sensorboard.peripheral.LEDColor;
import com.sun.spot.util.*;
import javax.microedition.midlet.MIDlet;
import javax.microedition.midlet.MIDletStateChangeException;

public class HelloHttpProxy extends MIDlet {
    protected void startApp() throws MIDletStateChangeException {
        new BootloaderListener().start();   

        // Socket Proxy 経由でWebサーバにアクセスする
        HttpRequestor requestor = new HttpRequestor();
        String page = requestor.doGet("http://java.net/" );
        System.out.println(page);
        
        // ResponseCode == OK の場合は Blue、それ以外の場合は Red
        // 500ms 間隔で一番左のLEDを点滅させる
        ITriColorLED[] leds = EDemoBoard.getInstance().getLEDs();
        if (requestor.isOK()) {
            leds[0].setColor(LEDColor.BLUE);
        } else {
            leds[0].setColor(LEDColor.RED);
        }
        while (true) {
            leds[0].setOn();
            Utils.sleep(500L);
            leds[0].setOff();
            Utils.sleep(500L);            
        }
    }
    
    protected void pauseApp() {
    }
    
    protected void destroyApp(boolean arg0) throws MIDletStateChangeException {
    }
}

 

# Webアクセスの本体部分 (HttpRequestor クラス)

package org.sunspotworld.demo.http;

import java.io.InputStream;
import javax.microedition.io.Connector;
import javax.microedition.io.HttpConnection;

public class HttpRequestor {
    public static final int INACTIVE = 0;
    public static final int CONNECTING = 1;
    public static final int COMPLETED = 2;
    public static final int ERROR = 3;
    
    private int status = INACTIVE;
    private int responseCode = -1;

    public synchronized String doGet(final String url) {
        HttpConnection conn = null;
        InputStream in = null;
        StringBuffer result = new StringBuffer();
        setResponseCode(-1);
        
        try {
            setStatus(CONNECTING);
            
            conn = (HttpConnection) Connector.open(url);
            conn.setRequestMethod(HttpConnection.GET);
            conn.setRequestProperty("Connection", "close" );
            in = conn.openInputStream();
            
            int len = (int)conn.getLength();
            if (len > 0) {
                byte[] data = new byte[len];
                int actual = in.read(data);
                result.append(new String(data, 0, actual));
            } else {
                int ch;
                while ((ch = in.read()) != -1) {
                    result.append((char) ch);
                }                
            }

            setResponseCode(conn.getResponseCode());            
            setStatus(COMPLETED);
        } catch (Exception ex) {
            setStatus(ERROR);
            ex.printStackTrace();
        } finally {
            if (in != null) {
                try {
                    in.close();
                } catch (Exception ex) {
                    ex.printStackTrace();
                }
            }
            if (conn != null) {
                try {
                    conn.close();
                } catch (Exception ex) {
                    ex.printStackTrace();
                }
            }
        }

        return result.toString();        
    }

    
    public boolean isInactive() {
        return (getStatus() == INACTIVE) ? true : false;
    }
    
    public boolean isConnecting() {
        return (getStatus() == CONNECTING) ? true : false;
    }
    
    public boolean isCompleted() {
        return (getStatus() == COMPLETED) ? true : false;
    }
    
    public boolean isError() {
        return (getStatus() == ERROR) ? true : false;
    }
    
    public int getStatus() {
        return status;
    }
    
    private void setStatus(int status) {
        this.status = status;
    }
    
    public boolean isOK() {
        return (getResponseCode() == HttpConnection.HTTP_OK) ? true : false;
    }
    
    public int getResponseCode() {
        return responseCode;
    }
    
    private void setResponseCode(int responseCode) {
        this.responseCode = responseCode;
    }
}

 

次に、Sun SPOTをUSBケーブルでホストPCに接続して、アプリケーションを配備します。# NetBeans IDE 上で間単に実行できます。

(ちなみにSun SPOT 開発キットにはUSBケーブルが1本しか付属していないため、ここではminiBタイプのケーブルをもう1本別途用意しています)

さていよいよ実行です。NetBeans IDE上でメニューから実行を選択すると。。。

。。。

java.net へのアクセスに成功しました ;-)

# Socket Proxy へのアクセスログ

# NetBeans の出力ウィンドウ

# Sun SPOT!

。。。

上記ではすべてデフォルト値のまま実行しましたが、以下のパラメータをSun SPOTアプリケーションの MANIFEST.MF ファイルに設定できます。

  • com.sun.spot.io.j2me.socket.SocketConnection-BaseStationAddress: <IEEE address>
  • com.sun.spot.io.j2me.socket.SocketConnection-BaseStationPort: <radiogram port>
  • com.sun.squawk.io.j2me.http.Protocol-HttpProxy: <proxyaddress>:<port>

 上の2つはSocket Proxy と接続する際に使用するベースステーションを直指定するためのものです(指定しない場合はブロードキャストによる検索が接続に先立って実行されます)。最後のパラメータは、Socket Proxy の動作するホストPCがプロキシを介してインターネットにアクセスする場合に、プロキシのホスト名とポート番号を指定するために使用します。

。。。

Socket Proxy及びHTTPプロトコルサポートについては、

などで、有益な情報が得られます。

また、spots-sdk-demos からSubversion で最新のサンプルを取得すると、HTTPDemo という楽しいデモが見つかります。


投稿されたコメント:

コメント
  • HTML文法 不許可

Valid HTML! Valid CSS!

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