teratail header banner
teratail header banner
質問するログイン新規登録

回答編集履歴

3

追記

2022/01/15 08:33

投稿

退会済みユーザー
answer CHANGED
@@ -15,7 +15,7 @@
15
15
 
16
16
  質問者さんの案のようにポーリングすると、その頻度やクライアントの数、そしてそれを受けてサーバー側で行う処置の内容によっては、サーバーに過大な負荷を強いるかもしれません。
17
17
 
18
- と言って、asp:button は html に変換されてブラウザに送られると input type="submit" 要素になります。なので、それをクリックすると form が submit されます(即ち PostBack されます)。結果、質問に書いてある「非同期のため処理が先に行ってしまいボタンクリックイベントが終わってしまう」ということになります。
18
+ asp:button は html に変換されてブラウザに送られると input type="submit" 要素になります。なので、それをクリックすると form が submit されます(即ち PostBack されます)。結果、質問に書いてある「非同期のため処理が先に行ってしまいボタンクリックイベントが終わってしまう」ということになります。
19
19
 
20
20
  なので、その対応として、クリックしても submit などは起こらない input type="button" のボタンを追加し、それの click イベントで jQuery.ajax でサーバーに要求をかけ、期待する応答が返ってきたらクライアント側のスクリプトで asp:button をクリックするのが良いと思います。
21
21
 

2

2022/01/15 03:58

投稿

退会済みユーザー
answer CHANGED
@@ -1,152 +1,140 @@
1
- > 最低 Web サーバーが生きていることを確認できれば良いが、できれば Web サーバーの後ろにある
2
- DB サーバーまで生きていることを確認したい。それを ajax を使って非同期でやりたい
3
-
4
- サーバーにある Web アプリに手を加えることが可能ならば、その確認のための要求を受け応答を返す Web サービスとか HTTP ジェネリックハンドラを追加してはいかがですか。
5
-
6
- 要求を受けたら例えば "生きてます" という応答を返す(DB サーバの生存確認も必要なら SELECT クエリを投げてその応答を確認するとかしてから)ようにしておき、その url を ajax を使って非同期で呼び出して "生きてます" という応答を確認して生存を確認するとか。
7
-
8
- いつまで経っても応答が返ってこない場合が問題ですが、タイムアウトの処理は考えておられるそうですので、そのあたりは問題ないですよね?
9
-
10
- ---
11
-
12
- **追記**
13
-
14
- > javascriptコードあるbtnSecとasp.netbtnSecは同じIDです。
15
-
16
- > ただコメントとおりasp:buttonreturnが非同期ですのでAjaxの回答を待たずTrueを返してダイレクトしてしま現象が発生ししま
17
-
18
- asp:button は html に変換されてブラウザに送られると input type="submit" 要素になります。なので、それをクリックすると form が submit されます (リダイレクトではなくて PostBack されます)。同ボタンクリックイベントで ajax で非同期要求するころは避けられせん
19
-
20
- れに対応するた質問者さん
21
-
22
- > それ一定周期にしHiddenに値を保持することで
23
-
24
- というようにポーリングすることだと理解しています、その頻度やクライアントの数、そしてそれ受けてサーバー側で行う処置の内容よっは、サーバーに過大な負荷を強いるかもしれせん
25
-
26
- ということで、ポーリングしなくても済む以下の案を提案します。
27
-
28
- (1) クリックしても何も起こらない input type="button" 要素を追加する。
29
-
30
- (2) 上の (1) で追加したボタンの click イベントで ajax を使って非同期でサーバー側の特定の url を呼び出す。
31
-
32
- (3) 期待する応答が返ってきたらスクリプトで asp:button をクリックする。
33
-
34
- (4) ユーザーに直接 asp:button をクリックされては困るなら css を使って隠しボタンにする。
35
-
36
- 一応コードを書いて検証しましたので、そのコードを以下に載せておきます。
37
-
38
- **WebForm1.aspx**
39
-
40
- timeout: 5000 に設定しているので、5 秒以内に 200 応答があれば done に設定した function が実行されます。サンプルコードの要求先の Handler1.ashx は 3 秒待って応答を返すので timeout: 5000 なら done になります。timeout: 2000 とか 3 秒より短くすると fail になります。
41
-
42
- サーバー側のコードの書き方によっては何らかの問題で必要な処理ができない場合も 200 応答を返すこともあると思います。下のサンプルコードでは単純に "生きてます" という応答を確認していますが、実際はもう少し考えた方が良さそうです。
43
-
44
- ```
45
- <!DOCTYPE html>
46
-
47
- <html xmlns="http://www.w3.org/1999/xhtml">
48
- <head runat="server">
49
- <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
50
- <title></title>
51
- <script src="Scripts/jquery-3.4.1.js"></script>
52
- <script type="text/javascript">
53
- $(function () {
54
- $("#btnSec").on("click", function () {
55
- $.ajax({
56
- type: "get",
57
- url: "Handler1.ashx",
58
- timeout: 5000
59
- }).done(function (data) {
60
- if (data == "生きてます") {
61
- var hiddenbutton = document.getElementById("Button1");
62
- hiddenbutton.click();
63
- }
64
- }).fail(function () {
65
- $("#Label1").text("タイムアウトまたはサーバーエラー");
66
- });
67
- });
68
- });
69
- </script>
70
- <style type="text/css">
71
- .style1
72
- {
73
- display: none;
74
- }
75
- </style>
76
- </head>
77
- <body>
78
- <form id="form1" runat="server">
79
- <div>
80
- <input id="btnSec" type="button" value="反映" />
81
- <asp:Button ID="Button1" runat="server"
82
- OnClick="ClickBtnSection" CssClass="style1" />
83
- <asp:Label ID="Label1" runat="server" Text="Label1 初期値"></asp:Label>
84
- </div>
85
- </form>
86
- </body>
87
- </html>
88
- ```
89
-
90
- **WebForm1.aspx.cs**
91
-
92
- ```
93
- using System;
94
-
95
- namespace WebForms1
96
- {
97
- public partial class WebForm1 : System.Web.UI.Page
98
- {
99
- protected void ClickBtnSection(object sender, EventArgs e)
100
- {
101
- Label1.Text = "Button1 がクリックされました";
102
- }
103
- }
104
- }
105
- ```
106
-
107
- **Handler1.ashx.cs (HTTP ジェネリックハンドラ)**
108
-
109
- 上の (2) に書いた「特定の url」に該当するのがこれ。以下のコードでは単純に Thread.Sleep(3000) で 3 秒待ってから "生きてます" という応答を返すだけですが、イベントハンドラ ClickBtnSection が実行可能かを調べるコードを書いておくのが良いかもしれません。
110
-
111
-
112
- ```
113
- using System;
114
- using System.Collections.Generic;
115
- using System.Linq;
116
- using System.Web;
117
-
118
- namespace WebForms1
119
- {
120
- /// <summary>
121
- /// Handler1 の概要の説明です
122
- /// </summary>
123
- public class Handler1 : IHttpHandler
124
- {
125
-
126
- public void ProcessRequest(HttpContext context)
127
- {
128
- System.Threading.Thread.Sleep(3000);
129
- context.Response.ContentType = "text/plain";
130
- context.Response.Write("生きてます");
131
- }
132
-
133
- public bool IsReusable
134
- {
135
- get
136
- {
137
- return false;
138
- }
139
- }
140
- }
141
- }
142
- ```
143
-
144
- 上のコードの実行結果は以下のようになります。
145
-
146
- **timeout: 5000**
147
-
148
- ![イメージ説明](80c24c4ce5e476af50f7e07eb5dfc060.jpeg)
149
-
150
- **timeout: 2000**
151
-
152
- ![イメージ説明](5d9681f7ef439eab9f601ff08b801a61.jpeg)
1
+ > 最低 Web サーバーが生きていることを確認できれば良いが、できれば Web サーバーの後ろにある
2
+ DB サーバーまで生きていることを確認したい。それを ajax を使って非同期でやりたい
3
+
4
+ サーバーにある Web アプリに手を加えることが可能ならば、その確認のための要求を受け応答を返す Web サービスとか HTTP ジェネリックハンドラを追加してはいかがですか。
5
+
6
+ 要求を受けたら例えば "生きてます" という応答を返す(DB サーバの生存確認も必要なら SELECT クエリを投げてその応答を確認するとかしてから)ようにしておき、その url を ajax を使って非同期で呼び出して "生きてます" という応答を確認して生存を確認するとか。
7
+
8
+ いつまで経っても応答が返ってこない場合が問題ですが、タイムアウトの処理は考えておられるそうですので、そのあたりは問題ないですよね?
9
+
10
+ ---
11
+
12
+ **2022/1/15 追記**
13
+
14
+ ポーリングしないで済む案を私の回答欄に追記したのですが 1/12 のメンテナンス(と言うより破壊的な変更)で消えてしまいました。再度書く気力はなくしていたのですが、検証に使ったサンプルコードは自分の PC 残っていたのでそれをアップしておきます。
15
+
16
+ 質問者さんようポーングすると、その頻度やライアンの数、そしてそれを受けてサーバー側で行処置の内容によっは、サーバーに過大な負荷を強るかもれません
17
+
18
+ と言って、asp:button は html に変換されてブラウザに送られると input type="submit" 要素になります。なので、それをクリックすると form が submit されます(即ち PostBack されます)。結果、質問に書いてある「非期のため処理が先に行ってしまいボタンクリックイベントが終わってしまう」いうことになり
19
+
20
+ なので、対応として、クリックしても submit などは起こらない input type="button" のボタンを追加し、それの click イベントで jQuery.ajax でサーバーに要求をかけ、期待する応答が返ってきらクライアント側スクリプトで asp:button をクリックするのが良いと思います。
21
+
22
+ ユーザーに asp:button クリックされたくなければ CSS で非表示にしてください。
23
+
24
+ 上記期待通り動くか検証したンプルコドを以下載せおき
25
+
26
+
27
+ **.aspx**
28
+
29
+ timeout: 5000 と設定して下にコードを載せた HTTP ジェネリックハンドラ Handler1.ashx を呼び出しています。Handler1.ashx は 3 秒待って応答を返すので done の function が実行され、それにより asp:button がクリックされます。 timeout: 2000 にすると fail になります。
30
+
31
+ ```
32
+ <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="WebForm1.aspx.cs"
33
+ Inherits="WebForms1.WebForm1" %>
34
+
35
+ <!DOCTYPE html>
36
+
37
+ <html xmlns="http://www.w3.org/1999/xhtml">
38
+ <head runat="server">
39
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
40
+ <title></title>
41
+ <script src="Scripts/jquery-3.4.1.js"></script>
42
+ <script type="text/javascript">
43
+ $(function () {
44
+ $("#btnSec").on("click", function () {
45
+ $.ajax({
46
+ type: "get",
47
+ url: "Handler1.ashx",
48
+ timeout: 5000
49
+ }).done(function (data) {
50
+ if (data == "生きてます") {
51
+ var hiddenbutton = document.getElementById("Button1");
52
+ hiddenbutton.click();
53
+ }
54
+ }).fail(function () {
55
+ $("#Label1").text("タイムアウトまたはサーバーエラー");
56
+ });
57
+ });
58
+ });
59
+ </script>
60
+ <style type="text/css">
61
+ .style1
62
+ {
63
+ display: none;
64
+ }
65
+ </style>
66
+ </head>
67
+ <body>
68
+ <form id="form1" runat="server">
69
+ <div>
70
+ <input id="btnSec" type="button" value="反映" />
71
+ <asp:Button ID="Button1" runat="server"
72
+ OnClick="ClickBtnSection" CssClass="style1" />
73
+ <asp:Label ID="Label1" runat="server" Text="Label1 初期値"></asp:Label>
74
+ </div>
75
+ </form>
76
+ </body>
77
+ </html>
78
+ ```
79
+
80
+ **.aspx.cs**
81
+
82
+ ```
83
+ using System;
84
+
85
+ namespace WebForms1
86
+ {
87
+ public partial class WebForm1 : System.Web.UI.Page
88
+ {
89
+ protected void ClickBtnSection(object sender, EventArgs e)
90
+ {
91
+ Label1.Text = "Button1 がクリックされました";
92
+ }
93
+ }
94
+ }
95
+ ```
96
+
97
+ **Handler1.ashx** (下のコードは Handler1.ashx.cs のもの)
98
+
99
+ 要求を受けると 3 秒待って "生きてます" という応答を返します。実際は本番の asp:button クリックで期待されるサーバー側での操作ができるかを検証してその成否を応答として返すようにするのが良いと思います。
100
+
101
+ ```
102
+ using System;
103
+ using System.Collections.Generic;
104
+ using System.Linq;
105
+ using System.Web;
106
+
107
+ namespace WebForms1
108
+ {
109
+ /// <summary>
110
+ /// Handler1 の概要の説明です
111
+ /// </summary>
112
+ public class Handler1 : IHttpHandler
113
+ {
114
+
115
+ public void ProcessRequest(HttpContext context)
116
+ {
117
+ System.Threading.Thread.Sleep(3000);
118
+ context.Response.ContentType = "text/plain";
119
+ context.Response.Write("生きてます");
120
+ }
121
+
122
+ public bool IsReusable
123
+ {
124
+ get
125
+ {
126
+ return false;
127
+ }
128
+ }
129
+ }
130
+ }
131
+ ```
132
+
133
+ 上のコードの実行して[反映]ボタンをクリックした結果は、timeout: 5000 の場合:
134
+
135
+
136
+ ![イメージ説明](https://ddjkaamml8q8x.cloudfront.net/questions/2022-01-15/639f5a36-3251-41f3-9e6c-1fb9802908e6.jpeg)
137
+
138
+ timeout: 2000 の場合:
139
+
140
+ ![イメージ説明](https://ddjkaamml8q8x.cloudfront.net/questions/2022-01-15/8d2e91c6-2bcf-41ed-bedd-04aa51664ac8.jpeg)

1

追記

2022/01/11 03:03

投稿

退会済みユーザー
answer CHANGED
@@ -5,4 +5,148 @@
5
5
 
6
6
  要求を受けたら例えば "生きてます" という応答を返す(DB サーバの生存確認も必要なら SELECT クエリを投げてその応答を確認するとかしてから)ようにしておき、その url を ajax を使って非同期で呼び出して "生きてます" という応答を確認して生存を確認するとか。
7
7
 
8
- いつまで経っても応答が返ってこない場合が問題ですが、タイムアウトの処理は考えておられるそうですので、そのあたりは問題ないですよね?
8
+ いつまで経っても応答が返ってこない場合が問題ですが、タイムアウトの処理は考えておられるそうですので、そのあたりは問題ないですよね?
9
+
10
+ ---
11
+
12
+ **【追記】**
13
+
14
+ > javascriptコード内にあるbtnSecとasp.netのbtnSecは同じIDです。
15
+
16
+ > ただコメントのとおりasp:buttonのreturnが非同期ですのでAjaxの回答を待たずにTrueを返してリダイレクト?してしまう現象が発生してしまいました。
17
+
18
+ asp:button は html に変換されてブラウザに送られると input type="submit" 要素になります。なので、それをクリックすると form が submit されます (リダイレクトではなくて PostBack されます)。同じボタンのクリックイベントで ajax で非同期要求するとそこのところは避けられません。
19
+
20
+ それに対応するための質問者さんの案が、
21
+
22
+ > それを一定周期にしHiddenにて値を保持することで
23
+
24
+ というようにポーリングすることだと理解していますが、その頻度やクライアントの数、そしてそれを受けてサーバー側で行う処置の内容によっては、サーバーに過大な負荷を強いるかもしれません。
25
+
26
+ ということで、ポーリングしなくても済む以下の案を提案します。
27
+
28
+ (1) クリックしても何も起こらない input type="button" 要素を追加する。
29
+
30
+ (2) 上の (1) で追加したボタンの click イベントで ajax を使って非同期でサーバー側の特定の url を呼び出す。
31
+
32
+ (3) 期待する応答が返ってきたらスクリプトで asp:button をクリックする。
33
+
34
+ (4) ユーザーに直接 asp:button をクリックされては困るなら css を使って隠しボタンにする。
35
+
36
+ 一応コードを書いて検証しましたので、そのコードを以下に載せておきます。
37
+
38
+ **WebForm1.aspx**
39
+
40
+ timeout: 5000 に設定しているので、5 秒以内に 200 応答があれば done に設定した function が実行されます。サンプルコードの要求先の Handler1.ashx は 3 秒待って応答を返すので timeout: 5000 なら done になります。timeout: 2000 とか 3 秒より短くすると fail になります。
41
+
42
+ サーバー側のコードの書き方によっては何らかの問題で必要な処理ができない場合も 200 応答を返すこともあると思います。下のサンプルコードでは単純に "生きてます" という応答を確認していますが、実際はもう少し考えた方が良さそうです。
43
+
44
+ ```
45
+ <!DOCTYPE html>
46
+
47
+ <html xmlns="http://www.w3.org/1999/xhtml">
48
+ <head runat="server">
49
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
50
+ <title></title>
51
+ <script src="Scripts/jquery-3.4.1.js"></script>
52
+ <script type="text/javascript">
53
+ $(function () {
54
+ $("#btnSec").on("click", function () {
55
+ $.ajax({
56
+ type: "get",
57
+ url: "Handler1.ashx",
58
+ timeout: 5000
59
+ }).done(function (data) {
60
+ if (data == "生きてます") {
61
+ var hiddenbutton = document.getElementById("Button1");
62
+ hiddenbutton.click();
63
+ }
64
+ }).fail(function () {
65
+ $("#Label1").text("タイムアウトまたはサーバーエラー");
66
+ });
67
+ });
68
+ });
69
+ </script>
70
+ <style type="text/css">
71
+ .style1
72
+ {
73
+ display: none;
74
+ }
75
+ </style>
76
+ </head>
77
+ <body>
78
+ <form id="form1" runat="server">
79
+ <div>
80
+ <input id="btnSec" type="button" value="反映" />
81
+ <asp:Button ID="Button1" runat="server"
82
+ OnClick="ClickBtnSection" CssClass="style1" />
83
+ <asp:Label ID="Label1" runat="server" Text="Label1 初期値"></asp:Label>
84
+ </div>
85
+ </form>
86
+ </body>
87
+ </html>
88
+ ```
89
+
90
+ **WebForm1.aspx.cs**
91
+
92
+ ```
93
+ using System;
94
+
95
+ namespace WebForms1
96
+ {
97
+ public partial class WebForm1 : System.Web.UI.Page
98
+ {
99
+ protected void ClickBtnSection(object sender, EventArgs e)
100
+ {
101
+ Label1.Text = "Button1 がクリックされました";
102
+ }
103
+ }
104
+ }
105
+ ```
106
+
107
+ **Handler1.ashx.cs (HTTP ジェネリックハンドラ)**
108
+
109
+ 上の (2) に書いた「特定の url」に該当するのがこれ。以下のコードでは単純に Thread.Sleep(3000) で 3 秒待ってから "生きてます" という応答を返すだけですが、イベントハンドラ ClickBtnSection が実行可能かを調べるコードを書いておくのが良いかもしれません。
110
+
111
+
112
+ ```
113
+ using System;
114
+ using System.Collections.Generic;
115
+ using System.Linq;
116
+ using System.Web;
117
+
118
+ namespace WebForms1
119
+ {
120
+ /// <summary>
121
+ /// Handler1 の概要の説明です
122
+ /// </summary>
123
+ public class Handler1 : IHttpHandler
124
+ {
125
+
126
+ public void ProcessRequest(HttpContext context)
127
+ {
128
+ System.Threading.Thread.Sleep(3000);
129
+ context.Response.ContentType = "text/plain";
130
+ context.Response.Write("生きてます");
131
+ }
132
+
133
+ public bool IsReusable
134
+ {
135
+ get
136
+ {
137
+ return false;
138
+ }
139
+ }
140
+ }
141
+ }
142
+ ```
143
+
144
+ 上のコードの実行結果は以下のようになります。
145
+
146
+ **timeout: 5000**
147
+
148
+ ![イメージ説明](80c24c4ce5e476af50f7e07eb5dfc060.jpeg)
149
+
150
+ **timeout: 2000**
151
+
152
+ ![イメージ説明](5d9681f7ef439eab9f601ff08b801a61.jpeg)