プロが教えるわが家の防犯対策術!

次のことをするcgiを作りたいのですが
 1. 起動したらデータを読み込み、その内容を表に表示。(即時)
 2. 5秒ごとにデータを読みに行き(ポーリング)、変化があったら表を
   リロードして新しいデータの表を表示する。

下記のようにすると、リロードされずに表がいくつも表示されてしまいます。
(リロード処理を入れてないので当たり前なんですが)
また、その表示が5秒ごとではなく、かなり長い時間(数十秒?)たってから
1度に数個表示されるというのを繰り返してしまいます。

 Q1 リロードさせるには、javascriptを使えばよいのかと思うのですが、
   どのようなスクリプトを使えばよいのでしょうか。
   また、javascriptでなくても他に方法があれば教えてください。
   (Perlのプログラム上では無理でしょうか)

 Q2 起動時にまずは最初のデータを表示させたいのですが、sleeを使うと
   起動後すぐ表示されないように思いますが、どのようにしたらよい
   でしょうか。

なお、下記テストプログラムでは、データを更新して表示する処理は
省いています。

よろしくお願い致します。

-------------------------
$kaisuu = 0;
$change = 0;

while (1) {
  &data;
  if($kaisuu == 0 ){
    &hyou;
    $kaisuu = 1;
  }elsif (($kaisuu == 1) && ($change == 1)){
    &hyou;
  }
  sleep 5;
}

sub data {
  #データの読み込み処理
  if(データに変化あり){
    $change = 1;
  }
}

sub hyou {
  print "Content-type: text/html\n";
  print "\n";
  print "<html>\n";
  print "<head>\n";
  print "<title>Test</title>\n";
  print "</head>\n";
  print " <table border=2 frame=border>\n";
  print " <tr><td>項目</td>\n";
  print " <td>名前</td></tr>\n";
  print " <tr><td>1</td>\n";
  print " <td>まるまる</td></tr>\n";
  print " <tr><td>2</td>\n";
  print " <td>ばつばつ</td></tr>\n";
  print " </table>\n";
  print "</body>\n";
  print "</html>\n";
}

A 回答 (4件)

Ajaxを使えばできそうな気がします。



setInterval(checkData,5000);

として5秒毎に、checkData関数を呼び出します。
checkData関数内では、Ajaxを使ってサーバーのデータを読み込み、現在のデータと照合し、更新していれば、

location.reload(true);

として、リロードさせます。
JavaScriptのカテゴリーで質問をすれば誰かが詳細コードを書いてくれると思います。
    • good
    • 0
この回答へのお礼

ありがとうございした。
JavaScript、ちょっと調べてみようと思います。

お礼日時:2010/01/31 18:45

>  1. 起動したらデータを読み込み、その内容を表に表示。

(即時)
>  2. 5秒ごとにデータを読みに行き(ポーリング)、変化があったら表を
>    リロードして新しいデータの表を表示する。

サーバープッシュCGIで可能です。
が、一部のブラウザは対応していないかもしれません。
(Content-Typeがmultipartの物に対応していない。
もしくは、サーバープッシュCGIを使う人がいなくなったため、ブラウザがサポートするのをやめた可能性がある。
または、単純に、私がテストしたmultipartの指定の仕方が悪かったとか。。。)

http://www.tohoho-web.com/wwwxx004.htm

sleepする直前にflush();しないと、STDOUTバッファに溜まったままになって、うまく表示が更新されないかもしれません。
$|=1;でもいいと思いますが、出力の効率が下がるんじゃないかと思います。


ネットワークをつなぎっぱなし、CGIアプリは動きっぱなしですから、ネットワークリソースやCPU負荷、メモリ使用量に注意して下さい。

通常はCGIで行わず、<meta>タグのrefreshかJavascriptのリロードを使うと思います。
Ajaxのはページ全体を書き換えるか(ページのリロード)、ページの一部を書き換えるか(Ajax)の違いだけです。
    • good
    • 0
この回答へのお礼

回答ありがとうございました。
サーバープッシュは調べたときに見つけたのですが、
IEを使用するため、対応してないとのことなので諦めました。
Javascriptでなんとか実現できないか、試してみようと思います。

お礼日時:2010/01/31 18:47

>私がやりたいのは、CGIでの処理を5秒ごとに行い、


>変化があったときのみリロードしたいのです。
 これは原理的に不可能なのです。
 HTTP通信の優れているところであると同時に、欠点。
 FTPでの通信だと、接続は保たれて、操作コマンドと処理結果コマンドは別ですし、コネクションは保たれますが、HTTPは要求、応答が一度限りなのです。どんなにあがいても、こればかりはどうしようもない。
 CGI側は、過去は知っているが未来は知らない。もし未来で変化するタイミングを知っているなら、
<meta http-equiv="refresh" content="5">
の5の値を変えて送信できるのだが・・
    • good
    • 0
この回答へのお礼

そうなんですか。
その辺のところはよくわかっていなかったもので。
別の方法(根本的に)を考えようと思います。
どうもありがとうございました。

お礼日時:2010/01/30 18:07

なにか思い違いされている。


reloadはブラウザへの指示
データを読み込みHTML出力は、CGIの処理

よって
sub hyou {
  print "Content-type: text/html\n";
  print "\n";
  print "<html>\n";
  print "<head>\n";
  print "<title>Test</title>\n";
print "<meta http-equiv="refresh" content="5">\n";
  print "</head>\n";

でもこんなまどろっこしい書き方をしなくても、print qq^^;でまとめればすっきりする。

この回答への補足

早々の回答ありがとうございます。

>print "<meta http-equiv="refresh" content="5">\n";

これだと5秒ごとにリロードしてしまいますよね?
(違ったらすいません)
私がやりたいのは、CGIでの処理を5秒ごとに行い、
変化があったときのみリロードしたいのです。

補足日時:2010/01/30 11:30
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!