- PR -

window.openだと処理を並列に行えない

投稿者投稿内容
さり
常連さん
会議室デビュー日: 2003/05/13
投稿数: 38
投稿日時: 2003-12-19 15:28
ASP.NETでWEBシステムを作成しています。
ブラウザのバージョンはIE6です。

あるウィンドウ(以下Aウィンドウ)から、もうひとつのウィンドウをwindow.openで開きます。
AウィンドウとBウィンドウで別々に処理を行いたいのですが、片方の処理が終了しないと、
片方のウィンドウの処理は始まらないのです。
2つブラウザを立ち上げて処理を行うと並列に処理を行う事ができます。

2つページを作成し、ボタンをサーバサイド処理で以下のように記述します。
コード:
Thread.Sleep(5000);



2つブラウザを立ち上げて、最初にAウィンドウのボタンを押し、1秒後にBウィンドウの
ボタンを押します。するとBウィンドウの処理はAウィンドウの処理の終了の1秒後に
終了します。

Aウィンドウを立ち上げ、そこからwindow.openメソッドでBウィンドウを立ち上げます。
再度、Aウィンドウのボタン押下の一秒後にBウィンドウのボタン押下を行うと、
Bウィンドウの処理終了はAウィンドウの処理終了の5秒後になってしまうのです。

こちらの処理が停止しているのがサーバサイドなのかクライアントサイドなのかを
調べるために、IISのログを見てみました。
コード:
20:18:20 192.168.1.2 POST /webapplication1/webform1.aspx 200
20:18:25 192.168.1.2 POST /webapplication1/webform2.aspx 200


このように記述したあったのですが、これはサーバサイドでレスポンスを返すときに
記述しているログなんですよね?となると、どこで処理が止まっているかは
分からないと結論しました。

まず、ブラウザでリクエストを出す所で止まっているのか、サーバサイドで処理が止まっているのか
を切り分けるために、パケットキャプチャソフトを入れて調査してみたのですが、
これだけのやり取りでも大量のパケットログが吐き出され、解析しようにも何が何だか分からず><

HTTPはステートレスなのだから、ブラウザを二つ立ち上げてきちんと処理が並列に出来ている以上、
問題はサーバサイドではなく、クライアントサイドにあると思っているのですが、原因を突き止める
方法と改善策が分からないのです。

改善策としても、モードレスで立ち上げたいので、showModalDialogメソッドは使えませんし、
window.openで立ち上げた場合は仕方のないことなのでしょうか?

すみません、アドバイスをお願いします。
ほむら
ぬし
会議室デビュー日: 2003/02/28
投稿数: 583
お住まい・勤務地: 東京都
投稿日時: 2003-12-19 16:07
ども、ほらです。
個人的な予想ですのであまり当てにはならないかもしれませんが。
--------
現象から察するにサーバーサイドのプログラムに問題があると思います。
おそらく、もう1つページ作ってこのページから
ウィンドウBを開いたあとにウィンドウAへリダイレクトする形にすれば
動くなるようになると思います。

#サーバーサイドのプログラムが終了しなければブラウザで表示されることも無いので
#スクリプトが走らないということです。
#(スクリプトをHEADに書けば違うかもしれませんけど^^;;;;;)
#(基本的に出力しきらなければブラウザ上で解析もしませんよね)
#サーバーサイドの処理とクライアントサイドの処理の区別はつけたほうがよいかと

もう一点
引用:

調べるために、IISのログを見てみました。
コード:
20:18:20 192.168.1.2 POST /webapplication1/webform1.aspx 200

20:18:25 192.168.1.2 POST /webapplication1/webform2.aspx 200



このように記述したあったのですが、これはサーバサイドでレスポンスを返すときに
記述しているログなんですよね?となると、どこで処理が止まっているかは
分からないと結論しました。


これは、レスポンスでなくリクエストです。
GETでなくてPOSTなのは.NETだからでしょうか?
なので、このログから見てもページのリクエストを送る時点で
遅延が発生していることもわかります

#以下追記
#あれ?なんか僕かなり思い違いしているような感じがする。。。
#どこでwindow.openをして、どこでsleep()かけているのでしょうか?
#sleep()しているのはページAのみ?

[ メッセージ編集済み 編集者: ほむら 編集日時 2003-12-19 16:16 ]
FOX
ベテラン
会議室デビュー日: 2002/04/08
投稿数: 63
お住まい・勤務地: いなか
投稿日時: 2003-12-19 16:43
こんにちは

私も興味が出たので同じ事をやってみました。

ただしページロード時に現在時刻をトレースに書き出すように細工をして実行しました。
ASP.NETのトレース情報によるとアクセス時間はほぼ同じなのにロードされた時間が5秒のずれが出ていました。
また別々にあげたIEに対しても同じことを行いましたがこっちは期待通り並列で処理されているようでした。

ここからは私の個人的な見解(思い込み?)です。

window.opneやctrl+n等で新たなウインドを上げた場合はASP.NETのセッションキーが同じものになります。
そのときASP.NETでは同じセッションとして処理が行われます。
同じセッションの要求に対してはASP.NETはセッションIDによるロックがかかるのでしょう。
#同時実行によるセッション等の破壊を防ぐためでしょうか?


さり
常連さん
会議室デビュー日: 2003/05/13
投稿数: 38
投稿日時: 2003-12-19 16:48
ヘタクソな説明で、すみません。
ほむらさま、レスありがとうございます。


>現象から察するにサーバーサイドのプログラムに問題があると思います。
>おそらく、もう1つページ作ってこのページから
>ウィンドウBを開いたあとにウィンドウAへリダイレクトする形にすれば
>動くなるようになると思います。
「Bを開いた後にAにリダイレクト」のあたりがちょっと分かりません。
「Bを開く」事はサーバサイドではなく、クライアントサイドで行っています。

ちょっと私の説明が悪かったのか、それとも理解が足りないのか
もう一度説明させて下さい。

WebForm1.aspxとWebForm2.aspxの二つのページを作ります。

WebForm1とWebForm2にWEBコントロールにボタンを付け、サーバサイドでのクリック時
のメソッドに、
Thread.Sleep(5000);     //5秒スリープ
を記述しています。
また、このThread.Sleepの行の前に、実行した時間を記録するようなログ処理を作っています。

また、WebForm1には、HTMLコントロールのボタンを付け、クライアントサイドでの
クリック時に、
window.open('WebForm2.aspx','new');
を行います。


二つブラウザを立ち上げ、片方(ウィンドウA)をWebForm1.aspx、片方(ウィンドウB)を
WebForm2.aspxを指定し、
5秒スリープのボタンを順番に押すと、その処理は同時に行われます。
ウィンドウAのボタンクリック → 1秒 → ウィンドウBのボタンクリック とした場合、
ログには1秒遅れでウィンドウBの処理が記録されています。

これは、クライアントサイドからウィンドウA・Bともにリクエストが別々に出され、
サーバでも別々に処理をされている、と理解しています。


ここで、ブラウザを一つだけ立ち上げ、Webform1.aspxを指定(ウィンドウA)します。
そして、window.openのクライアントメソッドが書かれているボタンを押下すると、
新しくウィンドウが開きます(ウィンドウB)。
(この時点ではAもBも処理は完了状態です。)
同じようにウィンドウAのスリープボタンを押したのちに、ウィンドウBのボタンを押すと、
ウィンドウAの処理が終了してから、ウィンドウBの処理が始まるような形になります。

先ほどと同じように、
ウィンドウAのボタンクリック → 1秒 → ウィンドウBのボタンクリック とした場合、
ログには5秒遅れでウィンドウBの処理が記録されています。

ここでクライアントサイドでリクエストを出すのがウィンドウBの方が5秒遅いのか、
サーバサイドでなんらかの仕掛けがあって、処理が5秒遅いのか確証が持てないのです。
ただ、サーバサイドでは二つのやり方の違いが判断できないと理解しているので、
クライアントの仕様なのかなぁ?と睨んでいる訳で・・・・(これも自信ナシ)

(長くなったので一度切ります)
さり
常連さん
会議室デビュー日: 2003/05/13
投稿数: 38
投稿日時: 2003-12-19 16:55
ほむらさま、重ね重ねではありますが、レスありがとうございます。

もう一方のIISのログについてですが、

コード:
20:18:20 192.168.1.2 POST /webapplication1/webform1.aspx 200
20:18:25 192.168.1.2 POST /webapplication1/webform2.aspx 200



「POST /webapplication1/webform1.aspx」はリクエストで、
「200」はレスポンスだと理解しています。
レスポンスが出ているので、この「20:18:25」時間部分は、レスポンスを
返す時間に書き込んでいるという理解は間違っていますでしょうか?



>#以下追記
>#あれ?なんか僕かなり思い違いしているような感じがする。。。
>#どこでwindow.openをして、どこでsleep()かけているのでしょうか?
>#sleep()しているのはページAのみ?
すみません、書き方が悪くて><
window.openしているのは、ウィンドウAのクライアントサイド、
sleetしているのは、A・B両方のサーバサイドです。
さり
常連さん
会議室デビュー日: 2003/05/13
投稿数: 38
投稿日時: 2003-12-19 17:10
FOX様、レスありがとうございます。

>window.opneやctrl+n等で新たなウインドを上げた場合はASP.NETの
>セッションキーが同じものになります。
>そのときASP.NETでは同じセッションとして処理が行われます。
>同じセッションの要求に対してはASP.NETはセッションIDによるロックが
>かかるのでしょう。
>#同時実行によるセッション等の破壊を防ぐためでしょうか?
えっと、ズバリでした。
Sessionを無効にして処理を行うと、window.openで立ち上げた場合も、
並列に処理を行う事ができました。

理由もFOX様のおっしゃるとおりだと思います。(これは憶測)


ただ、Sessionを無効にする事は要件上できないので、window.openした時に
別のセッションを与えられるような仕組みを調べてみます。
開き元のページで持っているセッションを、開き先のページに渡す必要は
ないので、なんとかなりそうな・・・・・
さり
常連さん
会議室デビュー日: 2003/05/13
投稿数: 38
投稿日時: 2003-12-19 18:38
window.openで開いたページに新しいセッションを与える方法は分かりました。
新しく開いたページの初期処理で、Response.Cookies["ASP.NET_SessionId"].Value
を直接編集してしまえばOKでした。

が、この方法では、きちんとユニークなセッションIDを与える事ができません。
.NET Frameworkの方で新しいセッションIDを与える方法は提供されているのでしょうか?



それと、上の方で「window.openで開いたページと開き元のページの処理が並列で
処理できない」原因は、「同一のセッションIDのリクエストはサーバ側では並列で
処理を行わない」という事でいいのでしょうか?もし御存知の方がいらっしゃったら
教えてください。
べる
ぬし
会議室デビュー日: 2003/09/20
投稿数: 1093
投稿日時: 2003-12-19 19:39
なにやら不思議(私がそう思うだけだとおもいますが)な現象ですね。

で、いま自分のマシン(で自分のマシンのWEBページを見る)で試してみたんですが
window.open('WebForm1.aspx')
のようにして開くと、確かに並列で処理されません。しかし、
window.open('http://(IPアドレス)/WebApplication1/WebForm1.aspx')

window.open('http://(マシン名)/WebApplication1/WebForm1.aspx')
のようにして開くと並列処理されました。
また、
window.open('http://localhost/WebApplication1/WebForm1.aspx')
ですと、並列処理されませんでした。

グローバルIPを持ってるマシン環境で確認できないのですが、
window.open('http://www.google.com/hoge/webform1.aspx');
みたいにしたらどうなるのでしょうね。

[編集]
関係あるかはわかりませんが、私のIEはプロキシを使用する設定になっています。
(ローカルアドレスにはプロキシサーバを使用しない設定にしています。)

[ メッセージ編集済み 編集者: べる 編集日時 2003-12-19 19:42 ]

スキルアップ/キャリアアップ(JOB@IT)