こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

締切り済みの質問

Perl JavaScript ページ自動更新

困っております・・・;;
お助けを・・・
目的・・・
Perlによる掲示版を設置しており
複数のユーザーが見ている中でも、誰かが
投稿すれば自動的に更新させたいのですが
どのようにするのでしょうか?
1、リアルタイムチャット的なものにしたいです


現在・・・
現在は、擬似的に
<script type='text/javascript'>
(function(){
var t = setInterval(function(){
location.reload(true);
}, 10000);
})();
</script>

このように10秒毎に、ページ更新
をし、
書込部分→write.cgi
表示部分→bbs.cgi
と分けており、表示部分を、Iframeにて
表示させ、書込途中でも、影響がないように
しました。

しかし、
これではリアルタイムではなく、
10秒毎に更新し続けるので、ユーザーが多い場合、
サーバー様に負荷をかけてしまいそうです・・・
さらに、更新されるたびに上へと、戻ってしまうので、閲覧中
であれば、不快に感じることも・・・

色々調べてはみているのですが、
Push通知、Socket.i.o、Comet、Ajax、Websocket
ポーリング、ロングポーリング、ストリーミング等といったことが
目的を果たせそうなのですが、

いずれも、使いかたがわからず、実行できておりません。

今参考にしているのは
http://engineer.recruit-lifestyle.co.jp/techblog/2015-07-29-node4/
このページ・・・
しかし、うまく実行できません

投稿日時 - 2017-10-31 12:45:48

QNo.9392100

困ってます

このQ&Aは役に立ちましたか?

0人が「このQ&Aが役に立った」と投票しています

回答(3)

ANo.3

setIntervalは「○ミリ秒間隔で次の関数を実行するようにしてね」ってことですので、開いた瞬間は実行されません。

var reload = function() {
$.ajax({
中略
});
}
setInterval(reload, 10000);
reload();
</script>

として初回のreload();を実行する方法もあるでしょう。
ただ、setIntervalはきっちり10秒間隔で実行されますので、前のデータ取得~表示が終わって無くてもお構いないしに関数が走ります。回線が細い場合などはデータを取得中なのに次のデータ取得関数も走り、次も次もとどんどんリソースを食いつぶして固まるでしょう。

ですので setTimeout を使ったほうが良いでしょう。
http://03log.me/blog/2014-05-29-js-setinterval-settimeout.html

投稿日時 - 2017-11-01 16:15:00

ANo.2

サーバー環境やいまのperlやデータファイルはそのまま使えたほうが
移行が楽でしょうから、私もajaxにするのが簡単だろうと思います。
(同時閲覧者数が多くて、サーバーでのプロセス数やコネクション数が
 問題になるような場合は別ですが)

まずは 10秒おきのreloadは取りやめてから

HTML内のJavaScriptで
・読み込み済の最新投稿の投稿番号(or投稿日時秒)をJavascriptの変数に取り出す
・その投稿番号(投稿日時)をjqueryの$.ajaxの送信データにして新規cgiへ送る

サーバー側の新規cgi (Perlでもなんでもいいけど) では
・上記の読み込み済の投稿番号(投稿日時秒)を受け取って
・サーバー上の投稿データにそれより新しいものがあれば、その投稿内容を
 JSONかXML形式に整えて返す。(複数新規があれば、複数itemで)
 (ロングポーリングとするなら、新しい投稿がなければ数秒sleepしてから
  再度投稿データと比較するのを タイムアウトしない時間以内で繰り返す)
・なにも新規投稿がなければ、空データでなく、0件であることがわかる
 JSON or XMLを返す

HTML側のajaxのsuccessのイベント処理で
・サーバーが返したJSON or XML をパースし
 それを表示中の画面にappendしていく(jqueryでのDOM操作)。
・最新の投稿番号(or投稿日時秒)を入れたJavascriptの変数を更新する。
・数秒後にこのajaxの再実行を予約する
  (ロングポーリングしないならいまと同じ10秒かな)。
って感じになるかと。

なお、文字モードがSJISやEUC-JPだと 文字化けしやすいので、
HTMLとCGIの返しをUTF-8に統一したほうが楽です。

投稿日時 - 2017-11-01 11:01:53

ANo.1

node.jsはひとまず忘れた方が良いと思います。

車の整備もできないのに、F1車のメンテナンスをしようとしてるようなもんだと思います。

とりあえず、10秒に一回でもいいではないですか。
まずはページごとリロードさせるという力技をやらずに、新規チャットが入った場合に必要なhtmlタグだけjavascriptでページに追加してあげましょう。そうすればiframeなんて使わずに済みます。

全部は回答できませんのでキーワードだけ書かせていただきます。

ページを更新せずにサーバに問い合わせ → キワード「ajax」

要素を追加
http://javascriptist.net/ref/element.appendChild.html

要素を追加 jqueryを使う場合
https://qiita.com/nekoneko-wanwan/items/227ccad5f8cc449e91e9

投稿日時 - 2017-10-31 19:10:30

お礼

ありがとうございます。

Ajaxで調べているうちに行き着いた現在の答えが

<script src="https://code.jquery.com/jquery-3.0.0.min.js"></script>
<script>
var reload = function() {
\$.ajax({
url: 'bbs.cgi?name=$NAME',
dataType: 'text',
success: function(data) {
\$('#text').html(data);
},
error: function(data) {
alert('error');
}
});
}
setInterval(reload, 10000);
</script>

スマホ(iPhone)では通常に動作しております。
しかし、ブラウザ(ie)で動かないです。
というより読込が遅い?
新しい情報になるのに時間がかかる?
古い情報が残っている?

またiframeを使わず、表示することには成功しました。
しかし、10秒待たないと、情報がでてこず、
1回目のみは、すぐ表示というのは、どうするのでしょうか?
もしくは、キーワードを教えてください;;

投稿日時 - 2017-11-01 14:02:12