クラサバとエージェント

戻る
::::::::::::::
result.txt
::::::::::::::
$ ./Agent.sh 

-- listing properties --
portNumber=80
messageEncoding=Shift_JIS

Server started...

-- listing properties --
defaultConnectTimeout=3000
defaultReadTimeout=5000
serverPortNumber=80
serverHostName=192.168.0.2
messageEncoding=Shift_JIS

Agent started...

装置名=読取装置A (deviceId=001): イベントを取得しています!
        /*** DEBUG ***/ connecting... hostName=192.168.0.2 portNumber=80
java.nio.channels.SocketChannel[connected local=/192.168.0.2:80 remote=/192.168.0.2:1231] connect.

時刻: Sun Jul 10 23:24:05 JST 2005
[クライアントからの要求電文]
DEVICEID: 1
OPERATOR: 岸 康弘
PROCEDURE: 登録
TIMESTAMP: 2005-07-10 23:24:05

この要求の受付番号=1
サーバ側からの応答: 受け取りました! 受付番号=1
装置名=読取装置B (deviceId=002): イベントを取得しています!
        /*** DEBUG ***/ connecting... hostName=192.168.0.2 portNumber=80
java.nio.channels.SocketChannel[connected local=/192.168.0.2:80 remote=/192.168.0.2:1232] connect.

時刻: Sun Jul 10 23:24:05 JST 2005
[クライアントからの要求電文]
DEVICEID: 2
OPERATOR: 山田 太郎
PROCEDURE: 検査
TIMESTAMP: 2005-07-10 23:24:05

この要求の受付番号=2
サーバ側からの応答: 受け取りました! 受付番号=2

::::::::::::::
Agent.sh
::::::::::::::
#!/bin/sh

PKGNAME=AgentBasedTracker
CLASSPATH=.\;../../lib/${PKGNAME}.jar

java -cp ${CLASSPATH} ${PKGNAME}.Server &
sleep 1

java -cp ${CLASSPATH} ${PKGNAME}.Agent


::::::::::::::
AbstractProcedure.java
::::::::::::::
package AgentBasedTracker;

import java.util.*;
import java.io.*;

/**
$Id: Agent.html,v 1.1 2009/06/22 16:11:36 kishi Exp kishi $
*/

public class AbstractProcedure {
    protected String name;

    protected AbstractProcedure( String name ) {
        this.name = name;
    }

    protected String getName() {
        return name;
    }

}

::::::::::::::
Agent.java
::::::::::::::
package AgentBasedTracker;

import java.util.*;
import java.io.*;

/**
$Id: Agent.html,v 1.1 2009/06/22 16:11:36 kishi Exp kishi $
*/

public class Agent implements Runnable {

    /** 監視対象のデバイス */
    private List deviceList;

    /** サーバのホスト名 */
    private String hostName;

    /** サーバのポート番号 */
    private int portNumber;

    /** サーバとやりとりするメッセージのエンコーディング */
    private String encoding;

    /** プロパティファイルのPATH */
    private String propFileName = "./agent-config.xml";

    public void addDevice( Device device ) {
        if ( deviceList == null ) {
            deviceList = new LinkedList();
        }

        // デバイスをエージェントの関係性を作成
        deviceList.add( device );
        device.setAgent( this );
    }

    public void getProperties() {
        // プロパティをロードする
        Properties prop = new Properties();
        try {
            InputStream stream = new FileInputStream( propFileName );
            prop.loadFromXML( stream );
            stream.close();

            // 一覧を出力
            prop.list( System.out );

            //=========================================================
            // 各プロパティを取得
            //=========================================================
            hostName = prop.getProperty( "serverHostName" );
            portNumber = new Integer( prop.getProperty( "serverPortNumber" ) ).intValue();
            encoding = prop.getProperty( "messageEncoding" );

            /******************************************************************************/
            /* 接続タイムアウトの設定; 設定された時間でコネクトできない場合はタイムアウト */
            /******************************************************************************/
            System.setProperty ( "sun.net.client.defaultConnectTimeout",
                                 ( String ) prop.getProperty( "defaultConnectTimeout" ) );

            /**********************************************************************************/
            /* 読み取りタイムアウトの設定; 設定された時間で読み取りできない場合はタイムアウト */
            /**********************************************************************************/
            System.setProperty ( "sun.net.client.defaultReadTimeout",
                                 ( String ) prop.getProperty( "defaultReadTimeout" ) );

        } catch ( IOException e ) {
            e.printStackTrace();
        }

    }

    public void start() {
        ( new Thread( this ) ).start();
    }

    public void run() {
        System.out.println();
        System.out.println( "Agent started..." );
        System.out.println();

        while ( true ) {

            // イベントの発生をチェックする
            checkEvents();

            try {
                Thread.sleep( 500 );
            } catch ( Exception e ) {
                e.printStackTrace();
            }
        }
    }

    /**
    * 登録されたデバイスからイベントの発生を確認する
    */
    private void checkEvents() {
        Iterator iterator = deviceList.iterator();
        while ( iterator.hasNext() ) {
            Device device = ( Device ) iterator.next();

            if ( device.hasEvent() ) {
                System.out.printf( "装置名=%s (deviceId=%03d): イベントを取得しています!\n",
                                   device.getName() , device.getId() );
                Event event = obtainEvent( device );
                Operator operator = event.getOperator();
                Procedure procedure = event.getProcedure();

                try {
                    Calendar date = Calendar.getInstance();
                    // サーバにメッセージを送信
                    communicate( "DEVICEID: " + device.getId()
                                 + "\n"
                                 + "OPERATOR: " + operator.getName()
                                 + "\n"
                                 + "PROCEDURE: " + procedure.getName()
                                 + "\n"
                                 + "TIMESTAMP: " + GenericUtils.getYYYYMMDD( date ) + " " + GenericUtils.getHHMISS( date )
                                 + "\n" );

                } catch ( Exception e ) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
    * デバイスから生成されたイベントを取得する
    * @param device デバイス
    */
    private synchronized Event obtainEvent( Device device ) {

        Event source = device.getEvent();
        Event destination = ( Event ) source.clone();

        device.destroyEvent();

        return destination;
    }

    /**
    * サーバに対して情報を送信する
    * @param message メッセージ
    */
    private void communicate( String message ) throws Exception {
        System.err.println( "\t/*** DEBUG ***/ connecting... hostName=" + hostName + " portNumber=" + portNumber );

        Client client = new Client();
        client.setEncoding( encoding );
        client.communicate( hostName, portNumber, message );

    }

    /** 単体試験 */
    static public void main( String[] args ) {

        Procedure registration = new Procedure( "登録" );
        Procedure inspection = new Procedure( "検査" );

        Device readerA = new Device( "読取装置A", 1 );
        Device readerB = new Device( "読取装置B" , 2 );

        Agent agent = new Agent();

        agent.getProperties();
        agent.addDevice( readerA );
        agent.addDevice( readerB );
        agent.start();

        User user1 = new User( 1, "岸 康弘" );
        User user2 = new User( 2, "山田 太郎" );

        user1.operate( readerA, registration );
        user2.operate( readerB, inspection );
    }
}
::::::::::::::
Client.java
::::::::::::::
package AgentBasedTracker;
import java.net.*;
import java.nio.*;
import java.nio.channels.*;
import java.nio.charset.*;
import java.util.*;

/**
$Id: Agent.html,v 1.1 2009/06/22 16:11:36 kishi Exp kishi $
*/

public class Client {

    private String encoding;
    private int bufferSize = 2048;

    public void setEncoding( String encoding ) {
        this.encoding = encoding;
    }

    public void communicate( String hostName, int portNumber, String message ) throws Exception {

        InetSocketAddress address = new InetSocketAddress( InetAddress.getByName( hostName ), portNumber );
        SocketChannel channel = SocketChannel.open(); // オープン
        channel.connect( address ); // サーバに接続

        Charset charset = Charset.forName( encoding );
        ByteBuffer request = charset.encode( message );
        channel.write( request ); // 書き込み

        ByteBuffer response = ByteBuffer.allocate( bufferSize );
        channel.read( response ); // 読み込み
        response.flip();
        System.out.println( "サーバ側からの応答: " + charset.decode( response ) );

        channel.close();

    }

    static public void main( String[] args ) throws Exception {

        Client client = new Client();
        client.setEncoding( "Shift_JIS" );
        client.communicate( "192.168.0.2", 80, "今晩は!" );

    }
}

::::::::::::::
Device.java
::::::::::::::
package AgentBasedTracker;
/**
$Id: Agent.html,v 1.1 2009/06/22 16:11:36 kishi Exp kishi $
*/

public class Device {

    private Agent agent;
    private String name;
    private int id;
    private Event event = null;

    public Device( String name , int id ) {
        this.name = name;
        this.id = id;
    }

    public int getId() {
        return id;
    }

    public String getName() {
        return name;
    }

    public void createEvent() {
        event = new Event();
    }

    public void destroyEvent() {
        event = null;
    }

    public boolean hasEvent() {
        return ( event != null );
    }

    public Event getEvent() {
        return event;
    }

    public void setAgent( Agent agent ) {
        this.agent = agent;
    }

}
::::::::::::::
Event.java
::::::::::::::
package AgentBasedTracker;
/**
* 
* $Id: Agent.html,v 1.1 2009/06/22 16:11:36 kishi Exp kishi $
* 
* @author KISHI Yasuhiro */ public class Event implements Cloneable { Operator operator; Procedure procedure; /** * 誰が操作したのかをセットする * @param operator 操作者 */ public void setOperator( Operator operator ) { this.operator = operator; } public Operator getOperator() { return operator; } public void setProcedure( Procedure procedure ) { this.procedure = procedure; } public Procedure getProcedure() { return procedure; } public Object clone() { return this; } } :::::::::::::: EventGenerator.java :::::::::::::: package AgentBasedTracker; /** $Id: Agent.html,v 1.1 2009/06/22 16:11:36 kishi Exp kishi $ @author KISHI Yasuhiro */ :::::::::::::: GenericUtils.java :::::::::::::: package AgentBasedTracker; import java.util.*; /** $Id: Agent.html,v 1.1 2009/06/22 16:11:36 kishi Exp kishi $ */ public class GenericUtils { /** 引数で与えた時刻からYYYY-MM-DD形式で日付を得る @param date 実行日付 @return YYYY-MM-DDで整形された日付 */ static public String getYYYYMMDD( Calendar date ) { int yy = date.get( Calendar.YEAR ); int mm = date.get( Calendar.MONTH ) + 1; String mm_str = ( mm < 10 ) ? "0" + String.valueOf( mm ) : String.valueOf( mm ); int dd = date.get( Calendar.DATE ); String dd_str = ( dd < 10 ) ? "0" + String.valueOf( dd ) : String.valueOf( dd ); return yy + "-" + mm_str + "-" + dd_str; } /** 引数で与えた時刻からHH:MI:SS形式で時刻を得る @param date 実行日付 @return HH:MM:SSで整形された時刻 */ static public String getHHMISS( Calendar date ) { int hh = date.get( Calendar.HOUR_OF_DAY ); // 24時間制の場合 String hh_str = ( hh < 10 ) ? "0" + String.valueOf( hh ) : String.valueOf( hh ); int mi = date.get( Calendar.MINUTE ) ; String mi_str = ( mi < 10 ) ? "0" + String.valueOf( mi ) : String.valueOf( mi ); int ss = date.get( Calendar.SECOND ); String ss_str = ( ss < 10 ) ? "0" + String.valueOf( ss ) : String.valueOf( ss ); return hh_str + ":" + mi_str + ":" + ss_str; } } :::::::::::::: Operator.java :::::::::::::: package AgentBasedTracker; /** $Id: Agent.html,v 1.1 2009/06/22 16:11:36 kishi Exp kishi $ */ public abstract class Operator { protected int id; protected String name; protected Operator( int id, String name ) { this.id = id; this.name = name; } protected String getName() { return name; } protected int getId() { return id; } /** * 指定したデバイスにて操作する */ abstract public void operate( Device device, Procedure procedure ); } :::::::::::::: Procedure.java :::::::::::::: package AgentBasedTracker; import java.util.*; import java.io.*; /** $Id: Agent.html,v 1.1 2009/06/22 16:11:36 kishi Exp kishi $ */ public class Procedure extends AbstractProcedure { public Procedure( String name ) { super( name ); } } :::::::::::::: Server.java :::::::::::::: package AgentBasedTracker; import java.io.*; import java.net.*; import java.util.*; import java.nio.*; import java.nio.channels.*; import java.nio.charset.*; /** $Id: Agent.html,v 1.1 2009/06/22 16:11:36 kishi Exp kishi $ @author KISHI Yasuhiro */ public class Server { /** 受付番号 */ private static int receptionNumber = 0; private Selector selector; private ServerSocketChannel serverSocketChannel; private int bufferSize = 2048; private int portNumber; private String encoding; /** プロパティファイルのPATH */ private String propFileName = "./server-config.xml"; public void getProperties() { // プロパティをロードする Properties prop = new Properties(); try { InputStream stream = new FileInputStream( propFileName ); prop.loadFromXML( stream ); stream.close(); // 一覧を出力 prop.list( System.out ); //========================================================= // 各プロパティを取得 //========================================================= portNumber = new Integer( prop.getProperty( "portNumber" ) ).intValue(); encoding = prop.getProperty( "messageEncoding" ); } catch ( IOException e ) { e.printStackTrace(); System.err.println( propFileName + "が見つかりません!" ); System.exit( 1 ); } } public void init() throws Exception { // プロパティの取得 getProperties(); selector = Selector.open(); serverSocketChannel = ServerSocketChannel.open(); serverSocketChannel.configureBlocking( false ); // 非同期モードにする InetSocketAddress address = new InetSocketAddress( InetAddress.getLocalHost(), 80 ); serverSocketChannel.socket().bind( address ); serverSocketChannel.register( selector, SelectionKey.OP_ACCEPT ); } public void invoke() throws Exception { System.out.println(); System.out.println( "Server started..." ); System.out.println(); while ( selector.select() > 0 ) { Set keys = selector.selectedKeys(); Iterator keyIterator = keys.iterator(); while ( keyIterator.hasNext() ) { SelectionKey key = ( SelectionKey ) keyIterator.next(); keyIterator.remove(); // 選択されたキーを削除 if ( key.isAcceptable() ) { ServerSocketChannel serverChannel = ( ServerSocketChannel ) key.channel(); SocketChannel socketChannel = serverChannel.accept(); socketChannel.configureBlocking( false ); // 非同期に変更 socketChannel.register( selector, SelectionKey.OP_READ ); System.out.println( socketChannel + " connect." ); } else if ( key.isReadable() ) { SocketChannel channel = ( SocketChannel ) key.channel(); communicate( channel ); } } } serverSocketChannel.close(); } private void communicate( SocketChannel socketChannel ) throws Exception { try { Object lock = new Object() ; Charset charset = Charset.forName( encoding ); // クライアントからのリクエストを読み込む ByteBuffer request = ByteBuffer.allocate( bufferSize ); socketChannel.read( request ); request.flip(); System.out.println(); System.out.print( "時刻: " + ( new Date() ).toString() ); System.out.println(); System.out.println( "[クライアントからの要求電文]\n" + charset.decode( request.duplicate() ) ); synchronized ( lock ) { receptionNumber ++; System.out.println( "この要求の受付番号=" + receptionNumber ); } // 返信メッセージを返す ByteBuffer response = charset.encode( "受け取りました! 受付番号=" + receptionNumber ); socketChannel.write( response ); socketChannel.close(); } catch ( Exception e ) { return ; } } static public void main( String[] args ) { Server server = new Server(); try { server.init(); server.invoke(); } catch ( Exception e ) { e.printStackTrace(); } } } :::::::::::::: User.java :::::::::::::: package AgentBasedTracker; /** * $Id: Agent.html,v 1.1 2009/06/22 16:11:36 kishi Exp kishi $ * @author KISHI Yasuhiro */ public class User extends Operator { public User( int id, String name ) { super( id, name ); } /** * デバイスを操作する⇒デバイスがイベントを生成する * @param device 操作するデバイス */ public void operate( Device device, Procedure procedure ) { // 操作する際の個人差などを個別に実装する ---> 機械との違いなど // (未実装) device.createEvent(); // 操作者として自身をセット ⇒ イベントと操作者の紐付け Event event = device.getEvent(); event.setOperator( this ); event.setProcedure( procedure ); } }
戻る inserted by FC2 system