2010年9月30日木曜日

[SA-3-5] 不要なサービスの自動起動設定解除

1.サービスの自動起動設定一覧表示
#chkconfig --list

2.不要なサービスの自動起動設定解除
#chkconfig (サービス名) off

例)chkconfig avahi-daemon off

[SA-3-4] 不要RPMパッケージの削除

1.外部と通信を行っているアプリケーションの,ポート番号とプロトコルを確認
#netstat -an

2.意図していない通信を行っているアプリケーションのポート番号とプロトコルから,プロセス名を確認
#yum install lsof
#/usr/sbin/lsof -i (プロトコル):(ポート番号)

例)/usr/sbin/lsof -i TCP:25

3.プロセス名から,RPMパッケージ名を調査
#yum whatprovides (プロセス名)

例)yum whatprovides sendmail

4.RPMパッケージの削除
#yum remove (RPMパッケージ名)

例)yum remove sendmail

5.その他不要なRPMパッケージをまとめて削除
yum remove wireless-tools cups isdn kudzu gpm smartd pcmcia

[SA-3-3] 現在のサーバの状態確認

1.Cent OS Version確認
#cat /etc/issue
#uname -a

2.メモリ使用量の確認
#free -m

3.ディスク使用量の確認
#df -H

4.稼働しているプロセスの確認
#ps aux

5.インストールされているアプリケーションの確認
#rpm -aq

6.installされているアプリケーションの数を表示
#rpm -aq | wc -l

7.自動起動設定されているアプリケーションの確認
#chkconfig --list

[SA-3-2] サーバーへのユーザー追加

1.ユーザーの追加
#adduser [user name]

2.作成したユーザーのパスワードを設定
#passwd [user name]

ちなみに,ユーザーの削除は
#userdel [user name]

3.作成したユーザーの環境変数にパスを通す

現在通っているパスの確認
#echo $PATH

パスを追加
#vi .bash_profile

変更前

PATH=$PATH:$HOME/bin

変更後
PATH=$PATH:$HOME/bin:/bin:/sbin

※以後,上記で作成したユーザーにてSSHを用いて外部から接続し,設定作業を行う.

[SA-3-1] VMware PlayerへのCentOS5.5インストール(最小構成)

※事前に,Windows上に仮想環境を構築するVMwarePlayerと,ネットワーク経由でインストールを行う際に使用するCentOSのISOイメージ(CentOS-5.5-i386-netinstall.iso)をダウンロードしておくこと.
今回構築するサーバは,必要最小限のアプリケーションのみのシンプルな構成とする事で,
トラブル時の調査に掛かる工数を低減し,各種アプリケーションのアップデート等に掛かるコストを軽減する事を目標とする.

0.VMware Player設定
・ゲストOSはLinux,バージョンはCentOS
・ハードウェアカスタマイズ→メモリ:256MB

1.テキストモードでインストールを行う.
boot : linux text
fig. 1

2.インストール時に使用する言語はEnglishで.
fig. 2

3.インストール時に使用するキーボードレイアウトの選択.

fig. 3

4.今回使用するインストールイメージは,ネットワーク経由でインストールに必要となるファイルを収集しながらインストールを進めるタイプのものです.今回はFTPを使用する事とします.

 fig. 4

5.FTPの接続先情報の入力画面です.
FTP Site name : ftp.iij.ad.jp
CentOS directory : pub/linux/centos/5.5/os/i386/
Use non-anonymous ftp : チェックなし
fig. 5

6.anonymous ftpを使用する際には,以下にユーザー情報を入力します(今回は不要です).
fig. 6

7.正常に通信が可能であれば,以下の画面が表示されます(しばらく時間が掛かります).
fig. 7

8.今回はテキストモードでインストールを進めます.
fig. 8

9.ここから(やっと)インストールが始まります.
fig. 9

10.今回は新規インストールの為,インストール先のパーティションを新規に作成します.
fig. 10

11.「全てのパーティションを削除し,デフォルトのパーティション配置を作成」を選択.
fig. 11

12.パーティション削除の確認.YESを選択.
fig. 12

13.パーティションレイアウトを確認.
fig. 13

14.自動的に作成されたパーティションレイアウトが表示されます.確認が終わったらYESを選択して次へ.
fig. 14

15.Boot LoaderとしてGRUBを使用.
fig. 15

16.特にBoot Loaderの設定は不要なので,何も入力せず次へ.
fig. 16

17.Boot Loaderのパスワードは今回は使用しないので,何も入力せず次へ.
fig. 17

18.記憶媒体を複数のパーティションに分割し,各パーティションにOSをインストールした場合,Boot Loaderから起動するOSを選択する事が出来ます.今回はCentOSのみの使用なので,特に設定は必要ありません.
fig. 18

19.Boot Loaderのインストール先設定です.MBRにインストールしましょう.
fig. 19

20.ネットワークインターフェース(eth0)の設定です.今回はネットワークに接続するサーバの構築ですので,ここで設定を行います.
fig. 20

21.起動時にネットワークインターフェースが利用できる設定とし,ネットワーク環境はIPv4とします.
fig. 21

22.VMWare Player側でNATを指定しているので,CentOS側ではDHCPを使用します(VMWare PlayerがCentOSにIP Addressを割り当てる事になります).
fig. 22

23.IP AddressはDHCP Serverが割り当てたものを使用します.
fig. 23

24.Time Zoneの設定です.Asia/Tokyoを選択.
fig. 24

25.rootのパスワード設定です.
fig. 25

26.インストールするパッケージの選択画面です.今回は必要最低限のアプリケーション環境とする為,この選択画面でチェックされている項目は全てチェックを外します.また,Customize software selectionにチェックを入れ,細かなパッケージもインストールしない事とします.
fig. 26

27.この選択画面でも,チェックされている項目は全てチェックを外します
fig. 27

28.これでCentOSのネットワークインストーラーで選択できる,最小限の環境でのインストールが開始されます.必要なアプリケーションは,後でインストールする事とします.
fig. 28

29.インストールするにあたり,パッケージ間の依存関係等のチェックが行われる為,若干時間が掛かります.
fig. 29

30.インストールが完了した際に表示される画面です.指示に従って再起動します.
fig. 30

31.通常の起動画面が表示されます.この画面で何かしらのキーを押すと,Boot Loaderのメニューが表示されます.ここでは特に何も触らず,起動されるのを待ちます.
fig. 31

32.起動が完了したらrootでログインします.後の作業はSSH経由でWindows側から行う為,IP Addressを確認します.
#ifconfig eth0
fig. 32

2010年9月29日水曜日

[memo] Cisco-Free Data Center

cisco製品なしで大規模データセンターを構築したことをHPが公表したそうです.

HP Data Centers Are 'Cisco-Free'(eWEEK.com)

HPがネットワーク通信機器ベンダー3COMを買収したことで,cisco製品なしでも大規模データセンターを構築できた事を発表しています.
逆に言えば,一般的なデータセンターではほぼ100%cisco製品が使われているわけで...

今回の公表の裏には,ciscoが従来のネットワーク機器ベンダーという立ち位置からCisco UCS B-Series(cisco)(*1)のようなサーバ製品をリリースする事で,データセンターの構築によりコミットしてきたのに対し,(従来は直接対立していなかった)cisco製品を除外する必要が出てきたからかもしれません.

今までは特定ベンダーに偏るリスクを嫌ってマルチベンダー戦略をとることが多かったですが,昨今のサーバ・ネットワークの仮想化が一般化した現状では,マルチベンダー環境では管理が煩雑になりすぎるため,思い切って単独ベンダー環境とし,専用の管理ツールを用いて,運用を簡便にするのも良いですね.


(*1)アラクサラネットワークスのシャシー型スイッチAX7800S(ALAXALA)は,通常のx86サーバ(OSはNetBSD?)の上にネットワーク処理専用のドーターカードが搭載されている形式の為,少し手を入れればスイッチとサーバの混在環境が単独筐体上に容易に構築出来るような気がするのですが...

2010年9月28日火曜日

[memo] タブレットコンピュータ雑感

昨今iPadに代表されるような,タッチディスプレイを搭載し,データの入力よりも閲覧が中心で,指による操作を行うガシェットが普及の兆しを見せている.
注意すべきポイントは,サイズ・用途等は似通っているが,それぞれ形状やハードウェアスペック,稼働するOS・アプリケーションが異なる事である.これは,この分野がまだまだ発展途上であり,決定打が登場していないことの表れでもある.
電子辞書が一般化し,紙の辞書を見かけなくなったのと同様に,新聞や一般の雑誌もいずれは電子化が進むと予想されるが,その流通も含めると普及にはもうしばらくの時間が掛かると思われる.そこで,現時点で発表されている多様な機種から,今後の流れを予想してみたいと思う.

以下に,現時点での代表的なタブレットコンピュータの一覧とコメントを掲載する.

1.タブレットコンピュータ
タッチディスプレイを搭載し,データの閲覧を主眼としたガシェット.
OSはPC用ではなく,タブレットコンピュータ専用のOSを使用する.

1-1.独自OS系

iPad(apple)
昨今のタブレットコンピュータの流れを作ったiPad.iPhoneと共通のOSを搭載しており,アプリケーションも(ほぼ)共通で動作する.

Kindle(amazon)
高性能・高機能ではないが,電子ブックを読むという事を主眼とした機種.母体がamazonである事から,電子ブックの購入・管理がAmazon経由で行える.流通も含めてのKindleといえる.

BlackBerry PlayBook(RIM)
小型端末ながらしっかりとしたキーボードを備えていた事で人気を集めていたBlackBerryからも,キーボードレスのタブレットコンピュータが登場.BlackBerryは企業ユーザーが多いことから,本機種も企業のシステムに組み込む事で利用できる事が利点か.

HP Slate(HP)
以前よりHP Slateの話は出ていましたが,搭載されるOSについては明言されていませんでした.しかし,今年Palmを買収した事から,Palmが開発したOSであるwebOSを搭載する事になったようです.
ただしHPは,AppleやAmazonのようにコンテンツホルダーでは無いことから,搭載OSについてはしがらみは少ないです.そのため,今後Windows/Android搭載のHP Slateが登場する可能性もあります.
現時点ではどのプラットフォームを選択する事がベストか分からないため全方位戦略とし,ある程度方向が定まったらプラットフォームを絞り込んでくると思われます.

1-2.Android系
今後機種数が増えていくと思われるジャンル.

GALAPAGOS(SHARP)
“ガラパゴス”という名前が挑戦的(皮肉?)なタブレットコンピュータ.日本語特有の表現に対応したXMDFフォーマットに対応したところがポイント.
日本経済新聞 電子版とも連携するらしい.
しかし...つい半年前にNetWarker(SHARP)を出しているんだけど,これはXMDFに対応するのかな?


2.タブレットPC
通常のWindwsが動作するPCでありながら,タブレットコンピュータの形状をしているタブレットPCは,その形状から,ノートPCの液晶部分が回転しタブレットPCスタイルにもなるコンパチブルタイプと,一枚の板状の筐体に液晶とPC本体を納めたピュアタブレット(スレート)タイプに2種類が存在する.

2-1.コンパチブルタイプ
Thinkpad X201Tablet(Lenovo)
主に業務用とで使用されるコンパチブルタブレットPC.工場や現場等のフィールドでPCが必要な場面で使われている.

Inspiron Duo(DELL)
変わった変形の仕方をするコンパチブルタブレット.

2-2.スレートタイプ
TW317(ONKYO)
タブレットコンピュータの形状ながら,フルスペックのWindowsが動作する事がポイント.電子ブック等利用したいコンテンツのフォーマットが固まっていない現状なら,今後どのようなフォーマットが普及しても使えるであろうWindows環境が利用できるのは利点.

Libretto W100(東芝)
世界初,2画面タッチパネル...だそうです.キーボード表示画面をアプリケーション毎にカスタマイズ出来るとおもしろいかも?CPUが意外とパワフル.


現時点では独自OS系のタブレットに勢いがありますが,今後Android搭載のタブレットが増加すると思われます.ただし本格的普及の為には,コンテンツホルダーとの合意も必要となるため,今後の流れに注視する必要がありそうです.

[memo] FD更新日付改竄事件

郵便不正事件に関連して,大阪地検特捜部の検事が証拠品として押収していたフロッピーディスク(FD)の更新日時を改竄していた事件の詳細が明らかになりました.

FD改ざん「あまりに稚拙」 矛盾ない書き換えは困難(asahi.com)

どのような手法を使って更新日時を改竄していたのか興味があったが,単にファイラーを用いてファイルの最終更新日時を変更した程度のようです.これでは最終アクセス日時が改竄を行った日時として残されてしまいます.
正しく(?)改竄を行うのであれば,ファイルの最終アクセス日時も証拠として矛盾無い日時とするべきでした.

今日主流のNTFSと比べて,FDで一般に使用されていたFAT12では,更新日時を更新した際に整合性を取るべき箇所は少なく,作成日時・最終更新日時・最終アクセス日時の3点が矛盾無く変更されていれば,表面上は問題が発覚しなかったはずです.
なので,今回の事件が明らかになったのは,FDで使用されている磁性体の変化を化学的に調査した結果だと思ったのですが...そこまで大がかりな案件ではなかったようです.


このように(今回の件はあまりにも稚拙だが),PCにおけるファイルの日時等は改竄可能なものであり,PC標準のファイル管理機構のみではファイルの正当性を担保する事は出来ません.
そこで,ファイルの正当性を担保するシステムとして,以下のようなものも存在します.

オリジナルデータセキュリティキット(canon)

このようなシステムを活用することで,データの改竄を防止する事が可能となるだけでなく,安易にデータを改竄しようと思う人に対する抑止力になると思われます.

2010年9月24日金曜日

[MA-8] 数字キーナビゲーション付きRSSリーダーの作成



ex10_RSS_Reader_6.swf

ActionScript2.0(Flash Lite2.1)
index_xml = new XML();
index_xml.onLoad = startIndexMenu;
index_xml.load("./feed.xml");
index_xml.ignoreWhite = true;
function startIndexMenu(success) {
 if (success == true) {
  var item = index_xml.firstChild.childNodes;
  item.shift();
  nodeNum = item.length;
  var temp:Array = [];
  _global.dateArray = new Array();
  _global.creatorArray = new Array();
  _global.titleArray = new Array();
  _global.linkArray = new Array();
  _global.descriptionArray = new Array();
  for (i=0; i<nodeNum; i++) {
   temp[i] = item[i].firstChild;
   temp[i] = temp[i].nextSibling;
   _global.dateArray[i] = temp[i].firstChild.nodeValue;
   temp[i] = temp[i].nextSibling.nextSibling;
   _global.creatorArray[i] = temp[i].firstChild.nodeValue;
   temp[i] = temp[i].nextSibling;
   _global.titleArray[i] = temp[i].firstChild.nodeValue;
   temp[i] = temp[i].nextSibling;
   _global.linkArray[i] = temp[i].firstChild.nodeValue;
   temp[i] = temp[i].nextSibling;
   _global.descriptionArray[i] = temp[i].firstChild.nodeValue;
  }
  date = _global.dateArray[0];
  creator = _global.creatorArray[0];
  title = _global.titleArray[0];
  link = _global.linkArray[0];
  description = _global.descriptionArray[0];
  _global.position = 0;
 }
}
rewindButton.onRelease = function() {
 if (_global.position == 0) {
  _global.position = 0;
  date = _global.dateArray[position];
  creator = _global.creatorArray[position];
  title = _global.titleArray[position];
  link = _global.linkArray[position];
  description = _global.descriptionArray[position];
 } else {
  _global.position = _global.position-1;
  date = _global.dateArray[position];
  creator = _global.creatorArray[position];
  title = _global.titleArray[position];
  link = _global.linkArray[position];
  description = _global.descriptionArray[position];
 }
};
topButton.onRelease = function() {
 _global.position = 0;
 date = _global.dateArray[position];
 creator = _global.creatorArray[position];
 title = _global.titleArray[position];
 link = _global.linkArray[position];
 description = _global.descriptionArray[position];
};
forwordButton.onRelease = function() {
 if (_global.position == (nodeNum-1)) {
  _global.position = (nodeNum-1);
  date = _global.dateArray[position];
  creator = _global.creatorArray[position];
  title = _global.titleArray[position];
  link = _global.linkArray[position];
  description = _global.descriptionArray[position];
 } else {
  _global.position = _global.position+1;
  date = _global.dateArray[position];
  creator = _global.creatorArray[position];
  title = _global.titleArray[position];
  link = _global.linkArray[position];
  description = _global.descriptionArray[position];
 }
};

var key_obj:Object = new Object();
key_obj.onKeyDown = function():Void {
 var code = Key.getCode(); // or getAscii()
 if (code == 52 || code == Key.LEFT) {
  if (_global.position == 0) {
   _global.position = 0;
   date = _global.dateArray[position];
   creator = _global.creatorArray[position];
   title = _global.titleArray[position];
   link = _global.linkArray[position];
   description = _global.descriptionArray[position];
  } else {
   _global.position = _global.position-1;
   date = _global.dateArray[position];
   creator = _global.creatorArray[position];
   title = _global.titleArray[position];
   link = _global.linkArray[position];
   description = _global.descriptionArray[position];
  }
 } else if (code == 53 || code == Key.UP) {
  _global.position = 0;
  date = _global.dateArray[position];
  creator = _global.creatorArray[position];
  title = _global.titleArray[position];
  link = _global.linkArray[position];
  description = _global.descriptionArray[position];
 } else if (code == 54 || code == Key.RIGHT) {
  if (_global.position == (nodeNum-1)) {
   _global.position = (nodeNum-1);
   date = _global.dateArray[position];
   creator = _global.creatorArray[position];
   title = _global.titleArray[position];
   link = _global.linkArray[position];
   description = _global.descriptionArray[position];
  } else {
   _global.position = _global.position+1;
   date = _global.dateArray[position];
   creator = _global.creatorArray[position];
   title = _global.titleArray[position];
   link = _global.linkArray[position];
   description = _global.descriptionArray[position];
  }
 }
}
Key.addListener(key_obj);

ダウンロード

2010年9月16日木曜日

[SA-2-2] 対象とするサイトより値を抽出し,DBに格納するShell Scriptの作成

http://mizubousaiyokohama.jp/suii_point.cgi?point_code=546649

1.データ受け入れ先となるテーブルを作成
$ mysql -u [user name] -p[password] [database name]
create table river_water_level (
 id integer NOT NULL AUTO_INCREMENT PRIMARY KEY,
 observation_time char(20),
 river_water_level char(20)
);

2.Shell Scriptの作成
指定した部分を正しく抜き出せるか確認
$ curl --silent --location 'http://mizubousaiyokohama.jp/suii_point.cgi?point_code=546649' | iconv -t UTF-8 -f SHIFT-JIS | grep -A 10 'suii_now_image_1.*.gif' | sed 's/<[^>]*>//g' | sed '1,8d' | cut -d " " -f 2 | sed '2,3d' | sed 's/-$/0/g'

指定した部分を正しく抜き出せたら,Shell Scriptに組み込む
$ vi get_river_water_level.sh
#!/bin/sh
observation_time=`date +%Y%m%d%H%M%S`

#横浜市水防災情報サイトより河川水位情報取得し,該当部分抜き出し
str_river_water_level=`curl --silent --location 'http://mizubousaiyokohama.jp/suii_point.cgi?point_code=546649' | iconv -t UTF-8 -f SHIFT-JIS | grep -A 10 'suii_now_image_1.*.gif' | sed 's/<[^>]*>//g' | sed '1,8d' | cut -d " " -f 2 | sed '2,3d' | sed 's/-$/0/g'`

echo "insert into river_water_level (observation_time,river_water_level) values ("$observation_time","$str_river_water_level");" >> temp_river_level.sql

/usr/bin/mysql -u [user name] -p[password] -s [database name] < temp_river_level.sql
rm temp_river_level.sql
exit 0

3.Shell Scriptへの実行権限付与
$ chmod u+x get_river_water_level.sh

4.Shell Scriptの実行
$ ./get_river_water_level.sh

5.シェルスクリプトを用いてMySQLに値が登録された事の確認
$ mysql -u [user name] -p [database name]
select * from river_water_level;

6.crontabへの登録
$ crontab -e
6,16,26,36,46,56 * * * * /home/[user name]/get_river_water_level.sh &

7.crontabに正しく登録されたか確認
$ crontab -l

[SA-2-1] 共有サーバに新しいデータベースの作成

1. サーバに接続
IPアドレス:10.2.3.100
ユーザー名:(gc301-gc320, is301-is308)
パスワード:**********

2. MySQLに接続
$ mysql -u [user name] -p [database name]
※ユーザー名とデータベース名は共通です

3. テーブルの作成
作成するテーブルの内容
idnew_tablenumberclassnamememo
11gcayabe
22gcishii
33gckitami
44gckuga
57gcgotou
68gcsatou
79gcshinada
810gctakahashi
911gctanaka
1015gchorimatsu
1117gcmuramatsu
1218gcmorota
1319gcyanagita
1420gcyamada
151iskubota
162issatou
173istakahashi
184istsunoda
196ismasuda
207ismuranaka
218ismoriya

4. SQLの練習
自分の名前を抽出するSQL文
SELECT name FROM new_table WHERE number="1" AND class="gc";

[SA-1-9] MySQL WorkbenchからMySQLへ接続

MySQL Workbenchのダウンロードとインストール
http://www-jp.mysql.com/downloads/workbench/

初期画面の画面左下「New Connection」を選択
fig. 4


接続設定を入力
fig. 5


設定完了後,初期画面の「Open Connectioin to Start Querying」の下に,今登録した接続設定が追加されたので,以後この接続設定を用いてMySQLへ接続

[SA-1-8] Shell ScriptからMySQLへ接続

下記テストのデータ受け入れ先となるテーブルを作成
$ mysql -u [user name] -p [database name]
create table ping_result (
 id integer NOT NULL AUTO_INCREMENT PRIMARY KEY,
 target_address char(20),
 observation_time char(20),
 str_ping char(20)
);

$ get_data.sh
#!/bin/sh
observation_time=`date +%Y%m%d%H%M%S`

target_list=`/usr/bin/mysql -u [user name] -p[password] [database name] -e "select ip_address from server_list" | sed '1d'`

for target_address in $target_list
do
 str_ping=""
 str_ping=`ping -c 1 -t 1 $target_address -q | sed '1,3d' | grep '0 received'`
 
 if test -z $str_ping
 then
  str_ping="OK"
 else
  str_ping="NG"
 fi
 
 echo $target_address" : "$str_ping;
 echo "insert into ping_result (target_address,observation_time,str_ping) values ('"$target_address"','"$observation_time"','"$str_ping"');" >> temp.sql
done

/usr/bin/mysql -u [user name] -p[password] -s [database name] < temp.sql
rm temp.sql
exit 0

$ chmod u+x get_data.sh
$ ./get_data.sh

シェルスクリプトを用いてMySQLに値が登録された事の確認
$ mysql -u [user name] -p [database name]
select * from ping_result;

Linuxの自動実行機能を用いて,定期的にシェルスクリプトが動作するように設定
.crontab
# +------------ 分 (0 - 59)
# | +---------- 時 (0 - 23)
# | | +-------- 日 (1 - 31)
# | | | +------ 月 (1 - 12)
# | | | | +---- 曜日 (0 - 6) (日曜日=0)
# | | | | |
# * * * * * 実行されるコマンド

#=================================================================
# get_data.sh
#毎時5,15,25,35,45,55分に情報取得・DB登録
#=================================================================

5,15,25,35,45,55 * * * * /home/[user name]/get_data.sh &

[SA-1-7] JavaからMySQLに接続

mysql-connector-java-5.1.8-bin.jarをダウンロードし,C:\Program Files\Javaに配置する.

JAVAのIDEを使用していない人は,開発ツール(Eclipse 3.5)をダウンロードし,インストールしておくと便利です.

connect_mysql.java
package connect;
import java.sql.*;

public class connect_mysql {
 public static void main(String[] args) {
  String url = "jdbc:mysql://10.2.3.100:3306/[database name]";
  String user = "[user name]";
  String pass = "[password]";
  
  if (args.length != 1) {
   System.out.println("usage: java connect_mysql [host_name]");
   System.exit(1);
  }
  
  try {
   Class.forName("com.mysql.jdbc.Driver");
   Connection con = DriverManager.getConnection(url, user, pass);
   
   String sql = "SELECT * FROM server_list where host_name = ?";
   PreparedStatement stmt = con.prepareStatement(sql);
   stmt.setString(1, args[0]);
   ResultSet res = stmt.executeQuery();
   if (res.next()) {
    System.out.println(res.getString(1) + ", " + res.getString(2) + ", " + res.getString(3) + ", " + res.getString(4));
   } else {
    System.out.println(args[0]);
    System.out.println("該当なし");
   }
   res.close();
   stmt.close();
   con.close();
  } catch (Exception e) {
   System.out.println("エラー");
   e.printStackTrace();
  }
 }
}

[SA-1-6] JavascriptからMySQLに接続

実際にサーバに設置したjavascriptからMySQLに接続する例
index.html : ベースファイル
xmlhttp.js : フォームに入力された文字列を,リアルタイムにbackend.phpに渡し,結果を受け取る(index.htmlとbackend.phpの仲介役)
backend.php : DBに接続し,結果をXMLとして出力(出力例)

index.html
<html>
<head>
    <meta http-equiv=content-type content="text/html; charset=UTF-8">
 <title>server_list search result</title>
 
 <STYLE TYPE="text/css">
 <!--
 .table1 {
  width: 400px;
  border-collapse: collapse;
  border: 1px #708090 solid;
 }
 .table1 TD {
  border: 1px #708090 solid;
 }
 -->
 </STYLE> 
 
    <script type="text/javascript" src="xmlhttp.js"></script>
    <script type="text/javascript">
    <!--
    findText = findTextOld = "";

    function loadXmlFile(fName){
        httpObj = createXMLHttpRequest(displayData);
        if (httpObj){
            httpObj.open("GET",fName,true);
            httpObj.send(null);
        }
    }

    function displayData(){
        if ((httpObj.readyState == 4) && (httpObj.status == 200)){
            xmlData = httpObj.responseXML;
            $("result").innerHTML = parseXmlData(httpObj.responseText);
        }else{
            $("result").innerHTML = "Loading ...";
        }
    }

    function parseXmlData(xmlData){
        $("result").innerHTML = xmlData;
        idListTags = document.getElementsByTagName("id");
        numListTags = document.getElementsByTagName("num");
        host_nameListTags = document.getElementsByTagName("host_name");
        ip_addressListTags = document.getElementsByTagName("ip_address");
        idLen = idListTags.length;

        resultText = "<table class='table1'><tr><th colspan=4>server_list search result</th></tr><tr><td><b>id</b></td><td><b>num</b></td><td><b>host_name</b></td><td><b>ip_address</b></td></tr>";
        for(i=0; i<idLen; i++){
            id = idListTags[i].childNodes[0].nodeValue;
            num = numListTags[i].childNodes[0].nodeValue;
            host_name = host_nameListTags[i].childNodes[0].nodeValue;
            ip_address = ip_addressListTags[i].childNodes[0].nodeValue;
            str = host_name.match(findText);
            if (str){
                resultText += "<tr><td>" + id + "</td><td>" + num + "</td><td>" + host_name + "</td><td><a href='http://" + ip_address + "' target='_blank'>" + ip_address + "</a></td></tr>";
            }
        }
        resultText += "</table>";
        return resultText;
    }

    function inputCheck(){
        findText = document.ajaxForm.requestText.value;
        if (findText != findTextOld) {
            str_search = "./backend.php?host_name=" + findText
            loadXmlFile(str_search);
            findTextOld = findText;
        }else{
//            $("result").innerHTML = "Loading ...";
        }
        setTimeout(" inputCheck()",500); // 0.5秒毎
    }

    window.onload = inputCheck;
    // -->
    </script>
</head>
<body>
<form name="ajaxForm" onSubmit="return false">
<input type="text" value="sa00" name="requestText">
</form>
<div id="result"></div>
</body>
</html>

xmlhttp.js
// HTTP通信用、共通関数
function createXMLHttpRequest(cbFunc){
 var XMLhttpObject = null;
 try{
  XMLhttpObject = new XMLHttpRequest();
 }catch(e){
  try{
   XMLhttpObject = new ActiveXObject("Msxml2.XMLHTTP");
  }catch(e){
   try{
    XMLhttpObject = new ActiveXObject("Microsoft.XMLHTTP");
   }catch(e){
    return null;
   }
  }
 }
 if (XMLhttpObject) XMLhttpObject.onreadystatechange = cbFunc;
 return XMLhttpObject;
}
 
// document.getElementById
function $(tagId){
 return document.getElementById(tagId);
}

backend.php
<?php
 $db_user  = "[user name]";
 $db_password = "[password]";
 $db_name = "[database name]";
 $db_host  = "localhost";

//create xml
    header('Content-type: text/xml; charset=utf-8');
    echo '<?xml version="1.0"?><sa>';

 $host_name = null;

 if(isset($_GET['host_name'])) {
  $host_name = $_GET['host_name'];

  $con = mysql_connect($db_host,$db_user,$db_password) or die("error!");
  mysql_select_db($db_name,$con) or die("DB is not exist");
  $strsql = "SET CHARACTER SET UTF8";
  mysql_query($strsql,$con);
  $strsql = "SELECT id, num, host_name, ip_address FROM server_list WHERE host_name LIKE '%".$host_name."%';";
  $res = mysql_query($strsql,$con);

  while ($item = mysql_fetch_array($res)) {
   print "<server_list><id>".$item[0]."</id><num>".$item[1]."</num><host_name>".$item[2]."</host_name><ip_address>".$item[3]."</ip_address></server_list>";
  }
  mysql_close($con);
    }

    echo '</sa>'; 
?>

1. 解凍したファイルを,/var/www/html/ajaxに配置
2. $ chmod 755 backend.php

[SA-1-5] PHPからMySQLに接続

実際にサーバに設置したPHPからMySQLに接続する例
select.php : SQL文を発行し,結果を表形式で出力
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>server_list</title>
</head>
<body>
<?php
 $db_user  = "[user name]";
 $db_password = "[password]";
 $db_name = "[database name]";
 $db_host  = "localhost";

 $db = mysql_connect($db_host,$db_user,$db_password);
 mysql_select_db($db_name,$db); 
 $str_sql = "select * from server_list";
 $rs = mysql_query($str_sql,$db);
 $num = mysql_num_fields($rs);

 print("<table><tr><th colspan=4>server_list</th></tr>");
 echo("
 ");
 print("<tr>");
 for ($i=0;$i<$num;$i++){
  print("<td><b>".mysql_field_name($rs,$i)."</b></td>");
 }
 print("</tr>");
 while($row=mysql_fetch_array($rs)){
  echo("
 ");
  print("<tr>");
  for($j=0;$j<$num;$j++){
   print("<td>".$row[$j]."</td>");
  }
  print("</tr>");
 }

 print("</table>");

 mysql_free_result($rs);
 mysql_close($db);
?>
</body>
</html>


1. 解凍したファイルを,/var/www/htmlに配置
2. $ chmod 755 select.php
3. サンプルで作成したPHPファイルを修正
1. テーブルの枠線を表示
2. 列の並びを「num, ip_address, host_name, id」に変更
3. idが3のもののみ表示

[SA-1-4] CSVファイルをDBに流し込む

$ mysql -u root -p sa
load data local infile "~/data/server_list.csv" into table server_list fields terminated by ',' enclosed by '"' lines terminated by '\n';
select * from server_list;

※Windows上でファイルを作成した場合は,改行コードが異なるため,「lines terminated」の指定の仕方が以下の様になります.
load data local infile "~/data/server_list.csv" into table server_list fields terminated by ',' enclosed by '"' lines terminated by '\r\n';

[SA-1-3] CSVファイルのアップロード

サーバ上で直接CSVファイルを作成せず,Windows環境でファイルを作成した場合,FTPツールを使ってサーバのホームディレクトリに「data」というディレクトリを作成し,その中にCSVファイルをアップロードします.
そしてアップロード後に,アップロードしたファイルのパーミッションを「755」に設定します.

※今回はSFTPを利用するので,SFTPが利用可能なクライアント(例:Filezilla)を使用してください.
http://filezilla-project.org/download.php?type=client
ホスト名:10.2.3.1**
ServerType:SFTP
ユーザー名:[user name]
パスワード:**********

[SA-1-2] CSVファイルの作成

id num server name ip address
1 sa000 10.2.3.100
2 sa001 10.2.3.101
3 sa002 10.2.3.102
4 sa003 10.2.3.103
5 sa004 10.2.3.104
6 sa005 10.2.3.105
7 sa006 10.2.3.106
8 sa007 10.2.3.107
9 sa008 10.2.3.108
10 sa009 10.2.3.109
11 sa010 10.2.3.110
12 sa011 10.2.3.111

$ vi server_list.csv
,1,sa000,10.2.3.100
,2,sa001,10.2.3.101
,3,sa002,10.2.3.102
,4,sa003,10.2.3.103
,5,sa004,10.2.3.104
,6,sa005,10.2.3.105
,7,sa006,10.2.3.106
,8,sa007,10.2.3.107
,9,sa008,10.2.3.108
,10,sa009,10.2.3.109
,11,sa010,10.2.3.110
,12,sa011,10.2.3.111

※UNIX上でファイルを作成した場合,一般的には改行コードはLFになります.

[SA-1-1] データベース,テーブルの作成

#mysqlに「root」として接続
$ mysql -u root -p

#データベース「sa」を作成
create database sa;
exit

#mysqlのデータベース「sa」に「root」として接続
$ mysql -u root -p sa

#テーブルが存在しないことを確認
show tables;

#テーブル「server_list」を作成
create table server_list (
 id integer NOT NULL AUTO_INCREMENT PRIMARY KEY,
 num char(4),
 host_name char(20),
 ip_address char(15)
);

#テーブル「server_list」が作成されたことを確認
show tables;

※間違えた場合はdropでテーブル削除

[SA-1-0] Fedora11インストール・設定

1.VM Ware PlayerにFedora11をインストール

2.ネットワーク設定を変更し,固定IPアドレスとする.
システム→管理→ネットワーク→編集
fig. 1

3.Webサーバの設定を変更し,Linux起動時にhttpdも同時に起動させる.
システム→管理→サービス
httpdの設定変更

4.index.html作成
$ cd /var/www/html
$ su
# vi index.html

5.index.php作成
$ cd /var/www/html
$ su
# vi index.php
<?php  phpinfo()? >

6.MySQLインストール
$ which mysql
# yum -y install mysql-server

7.MySQL設定
システム→管理→サービス→mysqld選択→設定変更
fig. 2


8.MySQLにログイン
$ chkconfig mysqld on
$ mysql -u root

# ユーザ情報表示
select user,host,password from mysql.user;


# 匿名ユーザー削除
delete from mysql.user where user='';


# rootパスワード設定
set password for root@localhost=password('[任意のパスワード]');


# rootパスワード設定
set password for root@'[ホスト名]'=password('[任意のパスワード]');


# rootパスワード設定
set password for root@127.0.0.1=password('[任意のパスワード]');


# ユーザーの追加
grant all privileges on *.* to [user name]@"%" identified by '[password]' with grant option;


# ユーザ情報表示
select user,host,password from mysql.user;


# ログアウト
exit


# rootログイン
$ mysql -u root -p

9.LinuxのFirewall設定で,MySQLのポートを許可
システム→管理→ファイアーウォール→その他のポート選択→追加→ポート:3306,プロトコル:TCP,サービス:mysql選択
fig. 3


10.ノートPCより,実機のMySQLサーバに接続
$ mysql -u [user name] -p -h 10.2.3.***




2010年9月9日木曜日

[卒業研究] ブラウザでの2Dハードウェアレンダリング

ブラウザでの画像・文字等の表示(レンダリング)にハードウェアを援用する試み.
従来は3Dオブジェクトにおいてはハードウェア(グラフィックカード等)を援用する形で,表示の高速化・高品質化を実現してきたが,それを2Dにも拡大したもの.
Firefox 4.0では2Dのアクセラレーションをデフォルトで有効化するとの事.

また,IE9ではJavaScriptエンジンがマルチコアCPUを利用してコンパイルしている.

※従来,ブラウザに最も求められていたものは互換性だったが,昨今では環境に依存する(つまり互換性をスポイルする)ハードウェアを利用してでも高速化したいという要求が高まっていることを示していると思われる.

参考
http://hacks.mozilla.org/2010/09/hardware-acceleration/

[卒業研究] Canvas or SVG?

ブラウザ上で高品質なグラフィックを扱う方法として,スケール可能(拡大縮小しても画像が荒れない)なフォーマットの使用が考えられる.
使用するブラウザのサポートが前提となるが,現時点ではHTML5のCanvas要素や,従来から存在するSVGを使用する方法が有力であろう.
しかしながら,それぞれ似て事なる技術の為,使用には注意が必要だ.

Canvas
・プログラミング可能
・Javascript必須

SVG
・グラフィックソフトのサポートあり
・データ形式はXML

※Canvasが開発者向けなのに対して,SVGはデザイナー向けと言えるかもしれません.

参考
http://www.sitepoint.com/blogs/2010/07/06/canvas-vs-svg-how-to-choose/

[memo] 岡崎図書館事件

岡崎図書館事件について,主にサーバ管理者の立場から気になる点をいくつか.

岡崎市立中央図書館で採用されているシステムは,三菱電機インフォメーションシステムズのMELIL/CS(旧型)である.
http://www.mdis.co.jp/news/topics/2010/0903.html

ニュースリリースの中で「大量アクセスによりつながらない、またはつながりにくい状態が発生し」とあるが,報道等から確認できる範囲では,アクセス間隔が1秒程度/1回あたりの情報収集に掛かる時間が30分程度と大量アクセスと呼べるほどのアクセスではなく,一般的な範囲に収まると個人的には感じている.

また報道によれば,岡崎市立中央図書館は図書館システムに問題はなく,了解を求めず大量アクセスを行なったことが問題であるという見解を示しているようだが,Webサーバに対して了解を求めずアクセスする事は一般的であり,大量アクセスを受けたと言っているが,その判断基準も曖昧である.
http://tomonken-weekly.seesaa.net/article/161880942.html


ちなみにSaaS形式の図書館システムもリリースされており,各図書館で管理しきれない場合には有効な手段だと思われる.
http://cloud.watch.impress.co.jp/docs/news/20100906_392065.html

参照
http://takagi-hiromitsu.jp/diary/20100829.html#p01

追記
岡崎市立中央図書館:利用者情報163人流出(毎日jp)
なんというか...アプリケーション開発体制の杜撰さが現れているような...

2010年9月1日水曜日

[MA-7] Flash Lite向けデジタル・アナログ時計



ex7_analg_digital_watch_lite2.swf

ActionScript2.0
action layer
this.onEnterFrame = function() {
 var DateObj:Date = new Date();
 var hour:Number = DateObj.getHours();
 var min:Number = DateObj.getMinutes();
 var sec:Number = DateObj.getSeconds();
 var youbi:Number = DateObj.getDay();
 var mon:Number = DateObj.getMonth();
 var date:Number = DateObj.getDate();
 var year:Number = DateObj.getFullYear();
 
 this.week.gotoAndStop(youbi+1);
 
 sHand._rotation = sec * 6;
 mHand._rotation = (min * 60 + sec) * 0.1;
 hHand._rotation = (hour * 60 + min) * 0.5;
 
 numDisp((hour*10000)+(min*100)+sec,6,"numMc");
 numDisp(((mon+1)*100)+date,4,"date");
 numDisp(year,4,"y");

}

function DigitAdjust(num,Digit:Number) {
 var newNum:String = num.toString();
 while(newNum.length < Digit) {
  newNum = "0" + newNum;
 }
 return newNum;
}

function numDisp(getNum:Number,keta:Number,str:String):Void {
 var i:Number = 0;
 var maxNum:Number = Math.pow(10,keta) - 1;
 var num:Number = Math.max(Math.min(getNum,maxNum),0);
 var strNum:String = "0000" + String(num);
 strNum = strNum.substr(strNum.length - keta,keta);
 for(i = 0;i < keta;i++) {
  this[str + i].gotoAndStop(Number(strNum.charAt(i)) + 1);
 }
}

stop();
digital layer
//デジタル時計
this.onEnterFrame = function() {
 var Dateobj:Date = new Date();
 var hour:Number = Dateobj.getHours();
 var minute:Number = Dateobj.getMinutes();
 var second:Number = Dateobj.getSeconds();
 var month:Number = Dateobj.getMonth()+1;
 var day:Number = Dateobj.getDate();
 var youbi:Number = Dateobj.getDay();
 var year:Number = Dateobj.getYear();
 this.numDisp(hour, 0, 2);
 this.numDisp(minute, 1, 2);
 this.numDisp(second, 2, 2);
 this.numDisp(month, 3, 2);
 this.numDisp(day, 4, 2);
 this.numDisp(youbi, 5, 1);
 this.numDisp(year, 6, 4);
 SetTime();
 tlD = setInterval(SetTime, 250);
};
function numDisp(getNum:Number, output:Number, keta:Number):Void {
 var i:Number = 0;
 var maxNum:Number = Math.pow(10, keta)-1;
 var num:Number = Math.max(Math.min(getNum, maxNum), 0);
 var strNum:String = "0000"+String(num);
 strNum = strNum.substr(strNum.length-keta, keta);
 for (i=0; i<keta; i++) {
  switch (output) {
  case 0 :
   this["numMcHour"+i].gotoAndStop(Number(strNum.charAt(i))+1);
   break;
  case 1 :
   this["numMcMin"+i].gotoAndStop(Number(strNum.charAt(i))+1);
   break;
  case 2 :
   this["numMcSec"+i].gotoAndStop(Number(strNum.charAt(i))+1);
   break;
  case 3 :
   this["MCmonth"+i].gotoAndStop(Number(strNum.charAt(i))+1);
   break;
  case 4 :
   this["MCday"+i].gotoAndStop(Number(strNum.charAt(i))+1);
   break;
  case 5 :
   this["MCyoubi"].gotoAndStop(Number(strNum.charAt(i))+1);
   break;
  case 6 :
   this["MCyear"+i].gotoAndStop(Number(strNum.charAt(i))+1);
   break;
  }
 }
}
function SetTime() {
 nowDate = new Date();
 hour = nowDate.getHours();
 min = nowDate.getMinutes();
 sec = nowDate.getSeconds();
 sHand._rotation = sec*6;
 mHand._rotation = (min*60+sec)*0.1;
 hHand._rotation = (hour*60+min)*0.5;
}
ダウンロード

[MA-6] Flash Lite向けストップウォッチ(Flash Lite)



ex6_stop_watch_lite2.swf

ActionScript2.0
startFlag = false;
nowTime = 0;
startTime = 0;
dispBaseTime = 0;
//
_root.onEnterFrame = function() {
 _root.numDisp(0, 0);
 _root.numDisp(0, 1);
 _root.numDisp(0, 2);
};
//
startButton.onRelease = function() {
 if (startFlag == false) {
  _root.startTime = getTimer() - _root.dispBaseTime;
  _root.onEnterFrame = displayUpdate;
  startFlag = true;
 } else {
  _root.onEnterFrame = null;
  startFlag = false;
 }
};
//
resetButton.onRelease = function() {
 _root.nowTime = 0;
 _root.startTime = 0;
 _root.dispBaseTime = 0;
 _root.startFlag = false;
 _root.onEnterFrame = null;
 _root.numDisp(0, 0);
 _root.numDisp(0, 1);
 _root.numDisp(0, 2);
};
//
function displayUpdate() {
 _root.nowTime = getTimer();
 _root.dispBaseTime = _root.nowTime - _root.startTime;
 milliSecond = Math.floor(dispBaseTime / 10);
 milliSecond = ("00" + milliSecond).substr(-2, 2);
 swSecond = Math.floor(dispBaseTime / 1000 % 60);
 if (swSecond < 10) {
  swSecond = "0" + swSecond;
 }
 minutae = Math.floor(dispBaseTime / 1000 / 60);
 if (minutae < 10) {
  minutae = "0" + minutae;
 }
 _root.numDisp(minutae, 0);
 _root.numDisp(swSecond, 1);
 _root.numDisp(milliSecond, 2);
}
//
var keta:Number = 2;
function numDisp(getNum:Number, output:Number):Void {
 var i:Number = 0;
 var maxNum:Number = Math.pow(10, keta) - 1;
 var num:Number = Math.max(Math.min(getNum, maxNum), 0);
 var strNum:String = "0000" + String(num);
 strNum = strNum.substr(strNum.length - keta, keta);
 for (i = 0; i < keta; i++) {
  switch (output) {
  case 0 :
   _root["numMcMinutae" + i].gotoAndStop(Number(strNum.charAt(i)) + 1);
   break;
  case 1 :
   _root["numMcSwSec" + i].gotoAndStop(Number(strNum.charAt(i)) + 1);
   break;
  case 2 :
   _root["numMcSwMiliSec" + i].gotoAndStop(Number(strNum.charAt(i)) + 1);
   break;
  }
 }
}
ダウンロード

[MA-5] ストップウォッチ



ex5_stop_watch.swf

各ムービークリップのインスタンス名
10の位numMcMinutae0
1の位numMcMinutae1
10の位numMcSwSec0
1の位numMcSwSec1
ミリ秒10の位numMcSwMiliSec0
1の位numMcSwMiliSec1

ActionScript2.0
startFlag = false;
firstFlag = false;
nowTime = 0;
startTime = 0;
dispBaseTime = 0;
//
_root.onEnterFrame = function() {
 _root.numDisp(0, 0);
 _root.numDisp(0, 1);
 _root.numDisp(0, 2);
};
//
startButton.onRelease = function() {
 if (startFlag == false) {
  if (firstFlag == false) {
   _root.startTime = getTimer() - _root.dispBaseTime;
   firstFlag = true;
  }
  _root.onEnterFrame = displayUpdate;
  startFlag = true;
 } else {
  _root.onEnterFrame = null;
  startFlag = false;
 }
};
//
resetButton.onRelease = function() {
 _root.nowTime = 0;
 _root.startTime = 0;
 _root.dispBaseTime = 0;
 _root.startFlag = false;
 _root.firstFlag = false;
 _root.onEnterFrame = null;
 _root.numDisp(0, 0);
 _root.numDisp(0, 1);
 _root.numDisp(0, 2);
};
//
function displayUpdate() {
 _root.nowTime = getTimer();
 _root.dispBaseTime = _root.nowTime - _root.startTime;
 milliSecond = Math.floor(dispBaseTime / 10);
 milliSecond = ("00" + milliSecond).substr(-2, 2);
 swSecond = Math.floor(dispBaseTime / 1000 % 60);
 if (swSecond < 10) {
  swSecond = "0" + swSecond;
 }
 minutae = Math.floor(dispBaseTime / 1000 / 60);
 if (minutae < 10) {
  minutae = "0" + minutae;
 }
 _root.numDisp(minutae, 0);
 _root.numDisp(swSecond, 1);
 _root.numDisp(milliSecond, 2);
}
//
var keta:Number = 2;
function numDisp(getNum:Number, output:Number):Void {
 var i:Number = 0;
 var maxNum:Number = Math.pow(10, keta) - 1;
 var num:Number = Math.max(Math.min(getNum, maxNum), 0);
 var strNum:String = "0000" + String(num);
 strNum = strNum.substr(strNum.length - keta, keta);
 for (i = 0; i < keta; i++) {
  switch (output) {
  case 0 :
   _root["numMcMinutae" + i].gotoAndStop(Number(strNum.charAt(i)) + 1);
   break;
  case 1 :
   _root["numMcSwSec" + i].gotoAndStop(Number(strNum.charAt(i)) + 1);
   break;
  case 2 :
   _root["numMcSwMiliSec" + i].gotoAndStop(Number(strNum.charAt(i)) + 1);
   break;
  }
 }
}
ダウンロード

[MA-4] 自作MCを用いたデジタル時計

1. ex4では,ex3で作成したムービークリップ,及びアクションスクリプトを流用するため,ex3で作成したファイルを複製する.
2. 1で複製したファイルを開く.
3. ex3で作成済みのシンボル1(ムービークリップ)を,fig. 1のようにステージ上に複数配置し,時分秒の区切り文字「:」を追加する.
fig. 1

4. 3でステージ上に配置した各ムービークリップは,ex3で作成したとおり,1~10のフレームに,数字の0~9が対応しているものとする(fig. 2).
fig. 2

5. 3でステージ上に配置したムービークリップのインスタンス名を以下のように変更する.
10の位numMcHour0
1の位numMcHour1
10の位numMcMin0
1の位numMcMin1
10の位numMcSec0
1の位numMcSec1

6. ムービークリップを配置したタイムラインに以下のASを記述

ActionScript2.0
this.onEnterFrame = function() {
 var DateObj:Date = new Date();
 var hour:Number = DateObj.getHours();
 var minute:Number = DateObj.getMinutes();
 var second:Number = DateObj.getSeconds();
 this.numDisp(hour, 0);
 this.numDisp(minute, 1);
 this.numDisp(second, 2);
 //this.numDisp(18);
 //stop();
};
var keta:Number = 2;
function numDisp(getNum:Number, output:Number):Void {
 var i:Number = 0;
 var maxNum:Number = Math.pow(10, keta) - 1;
 var num:Number = Math.max(Math.min(getNum, maxNum), 0);
 var strNum:String = "0000" + String(num);
 strNum = strNum.substr(strNum.length - keta, keta);
 for (i = 0; i < keta; i++) {
  switch (output) {
   case 0:
   this["numMcHour" + i].gotoAndStop(Number(strNum.charAt(i)) + 1);
   break;
   
   case 1:
   this["numMcMin" + i].gotoAndStop(Number(strNum.charAt(i)) + 1);
   break;
   
   case 2:
   this["numMcSec" + i].gotoAndStop(Number(strNum.charAt(i)) + 1);
   break;
  }
 }
}
ダウンロード

[MA-3] 自作オブジェクトを用いた数字の表示



ex3_pict_num.swf

1. メニューの挿入→新規シンボルから,ムービークリップ作成.
2. メニューの表示→グリッド→グリッドの編集から,グリッドの表示,及びグリッドに吸着にチェックを入れ,グリッド間隔を縦横2pxとする.
3. ステージ上に7セグメントディスプレイ表示の8を作成.
4. タイムラインの2フレーム目を選択し,挿入→タイムライン→キーフレームを選択.
5. タイムラインの3フレーム目から10フレーム目までも同様に,メニューの挿入→タイムライン→キーフレームを選択.
6. タイムラインの1フレーム目を選択し,ステージ上に表示されているオブジェクト(7セグメントディスプレイ表示の8)から,不要な部分を削除して数字の0とする.
7. 2フレーム目から10フレーム目までも同様に,各フレームで表示されるオブジェクトが,数字の1~9になるように,不要部分を削除する.
8. シーンの編集ボタンから,シーン1を選択.
9. メニューのウィンドウ→ライブラリを選択.
10. 9で開いたウィンドウ内の「シンボル1」をステージ上にDrag and Drop.
11. ステージ上に配置されたムービークリップを選択し,インスタンス名を「numMc0」とする.
12. 11で配置したムービークリップを複製し,インスタンス名を「numMc1」とする.
13. ムービークリップを配置したタイムラインに以下のASを記述
14. プレビュー画面で「18」と表示されていることを確認.

ActionScript2.0
var keta:Number = 2;

function numDisp(getNum:Number):Void {
 var i:Number = 0;
 var maxNum:Number = Math.pow(10, keta) - 1;
 var num:Number = Math.max(Math.min(getNum, maxNum), 0);
 var strNum:String = "0000" + String(num);
 strNum = strNum.substr(strNum.length - keta, keta);
 for (i = 0; i < keta; i++) {
  this["numMc" + i].gotoAndStop(Number(strNum.charAt(i)) + 1);
 }
}

this.numDisp(18);
stop();
ダウンロード

[MA-2] Analog Watch



ex2_analog_watch.swf

1.時計文字盤,秒針,長針,短針を作成
2.1で作成した各オブジェクトを選択して右クリック--->レイヤーに分配
3.秒針,長針,短針を選択して右クリック--->シンボルに変換(ムービークリップ)
4.秒針,長針,短針を配置した各レイヤーの1フレーム目のオブジェクトの位置を,時計文字盤の中心に揃える(オブジェクト右クリック--->編集,「+」の記号がオブジェクトの中心になるので,針の中心と一致させる).
5.秒針,長針,短針の各オブジェクトに,フィルタ--->ドロップシャドウを適用し,重なり合ったときの見栄えを考慮する.
6.23文字分のダイナミックテキストオブジェクト(インスタンス名は「daytime」)を作成し,デジタル時計レイヤーに分配する.

ActionScript2.0
onLoad = function () {
 SetTime();
 tlD = setInterval(SetTime, 250);
};

function SetTime() {
 nowDate = new Date();
 hour = nowDate.getHours();
 min = nowDate.getMinutes();
 sec = nowDate.getSeconds();
 sHand._rotation = sec * 6;
 mHand._rotation = (min * 60 + sec) * 0.1;
 hHand._rotation = (hour * 60 + min) * 0.5;

 year = nowDate.getFullYear();
 mon = AddZero(nowDate.getMonth() + 1);
 day = AddZero(nowDate.getDate()); 
 youbiArr = new Array("Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat");
 youbi = youbiArr[nowDate.getDay()];
 
 daytime.text = year + "/" + mon + "/" + day + "/" + "[" + youbi + "]" + AddZero(hour) + ":" + AddZero(min) + ":" + AddZero(sec);
}

function AddZero(num) {
 if (num < 10) {
  num = "0" + num;
 }
 return num;
}
ダウンロード

[MA-1] Digital Watch



ex1_digital_watch.swf

ActionScript2.0
//フレーム読み込み時に実行
this.onEnterFrame = function() {
 var ampm:String;
 var nowTime:String;

 var DateObj:Date = new Date();

 var hour:Number = DateObj.getHours();
 var minute:Number = DateObj.getMinutes();
 var second:Number = DateObj.getSeconds();

//午前午後判断
 if (hour >= 0 && hour < 12) {
  ampm = "am";
 } else if (hour >= 12 && hour <= 23) {
  ampm = "pm";
  hour -= 12;
 } else {
  ampm = "pm";
 }

//流し込む文字列の結合
 nowTime = ampm + DigitAdjust(hour, 2) + ":" + DigitAdjust(minute, 2) + ":" + DigitAdjust(second, 2);
 NowTimeView.text = nowTime;
};

//桁数変換
function DigitAdjust(num, Digit:Number) {
 var newNum:String = num.toString();
 while (newNum.length < Digit)
  newNum = "0" + newNum;
 return newNum;
};
ダウンロード

[MA-0] お知らせ

現在課題をアップロードする際に利用しているHPですが,2010年10月末でサービス終了だそうです.
http://mgrsato.hp.infoseek.co.jp/cgi-bin/uploader.cgi

現在代替手段を模索中ですので,しばらくお待ちください.

[SA-0] お知らせ

現在授業で使用しているサーバ(http://10.2.3.100/SA/)ですが,課題等を公開する部分を外部のサーバ(本blog)に移行しました.
これにより,課題の予習/復習が自宅でも行えるようになります.