回答編集履歴
3
追記
answer
CHANGED
@@ -15,7 +15,7 @@
|
|
15
15
|
|
16
16
|
質問者さんの案のようにポーリングすると、その頻度やクライアントの数、そしてそれを受けてサーバー側で行う処置の内容によっては、サーバーに過大な負荷を強いるかもしれません。
|
17
17
|
|
18
|
-
|
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
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
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
asp:button は html に変換されてブラウザに送られると input type="submit" 要素になります。なので、それをクリックすると form が submit されます
|
19
|
-
|
20
|
-
そ
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
</
|
76
|
-
</
|
77
|
-
<
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
}
|
142
|
-
```
|
143
|
-
|
144
|
-
上のコードの実行結果は以下のようになります。
|
145
|
-
|
146
|
-
**timeout: 5000**
|
147
|
-
|
148
|
-

|
149
|
-
|
150
|
-
**timeout: 2000**
|
151
|
-
|
152
|
-

|
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
|
+

|
137
|
+
|
138
|
+
timeout: 2000 の場合:
|
139
|
+
|
140
|
+

|
1
追記
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
|
+

|
149
|
+
|
150
|
+
**timeout: 2000**
|
151
|
+
|
152
|
+

|