-
Notifications
You must be signed in to change notification settings - Fork 4
/
337.txt
117 lines (105 loc) · 7.58 KB
/
337.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
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
* 仕様書
[REFS[
- [10] [CITE@en[RFC 6455 - The WebSocket Protocol]] ([TIME[2015-03-11 20:42:50 +09:00]] 版) <http://tools.ietf.org/html/rfc6455#section-5>
- [54] [CITE@en[RFC 6455 - The WebSocket Protocol]] ([TIME[2015-03-11 20:42:50 +09:00]] 版) <http://tools.ietf.org/html/rfc6455#section-6.2>
- [21] [CITE@en[RFC 6455 - The WebSocket Protocol]] ([TIME[2015-03-11 20:42:50 +09:00]] 版) <http://tools.ietf.org/html/rfc6455#section-8>
- [50] [CITE@en[RFC 6455 - The WebSocket Protocol]] ([TIME[2015-03-11 20:42:50 +09:00]] 版) <http://tools.ietf.org/html/rfc6455#section-10.4>
- [59] [CITE@en[RFC 6455 - The WebSocket Protocol]] ([TIME[2015-03-11 20:42:50 +09:00]] 版) <http://tools.ietf.org/html/rfc6455#section-10.7>
- [1] [CITE@en-GB-x-hixie[HTML Standard]] ([TIME[2015-05-06 10:42:35 +09:00]] 版) <https://html.spec.whatwg.org/#feedback-from-the-protocol>
]REFS]
* 処理
[6] [[WebSocket接続の確立]]により[[WebSocket接続]]の状態が [CODE[[[OPEN]]]]
になると、以後の受信データは次のように処理されることになります。
;; [5] [[WebSocket]] の規定に従わない[[クライアント]]は、 [[WebSocket handshake]]
における[[サーバー]]からの[[応答]]を待たずに[[フレーム]]
(や[[フレーム]]になっていないデータ) を送信するかもしれません。[[サーバー]]はそれに特別な対処を行う必要はありませんが、 >>60 を根拠に切断しても良いのかもしれません。
[53] 受信したデータは、次のように処理しなければ[['''なりません''']]。
[FIG(steps)[
= [9] [[WebSocketフレーム]]として構文解析します [SRC[>>54]]。
= [60] 不正なデータなら、[[TCP接続]]を切断して構いません。
次のようにする[['''べきです''']]。 [SRC[>>59]]
== [7] [[[CODE[Close]]フレーム]]を送信します。
== [8] [[WebSocket接続を閉じる]]処理を実行します。
== [15] 停止します。
= [14] 次の場合は、[[WebSocket接続失敗]]を実行し、停止します。 [SRC[>>10]]。
[FIG(list)[
- [16] [CODE[[[RSV1]]]] が非 [CODE[[[0]]]] 値であり、[[拡張]]のいずれの規定にも拠っていない場合
- [17] [CODE[[[RSV2]]]] が非 [CODE[[[0]]]] 値であり、[[拡張]]のいずれの規定にも拠っていない場合
- [11] [CODE[[[RSV3]]]] が非 [CODE[[[0]]]] 値であり、[[拡張]]のいずれの規定にも拠っていない場合
- [12] 未知の [CODE[[[opcode]]]] の場合
]FIG]
= [13] 自身が[[サーバー]]であり、[[フレーム]]が[[マスク]]されていないか、
自身が[[クライアント]]であり、[[フレーム]]が[[マスク]]されているなら、
== [19] [[[CODE[Close]]フレーム]]を[[状態符号]] [CODE(HTTP)[[[1002]]]] で送信して構いません
[SRC[>>10]]。
== [18] [[接続]]を閉じます [SRC[>>10]]。
= [58] 自身が[[サーバー]]なら、[[マスク]]を除去します [SRC[>>54]]。
= [55] [[制御フレーム]]なら、その規定により処理します [SRC[>>54]]。
([[[CODE[Close]]フレーム]], [[[CODE[Ping]]フレーム]], [[[CODE[Pong]]フレーム]]を参照。)
= [22] [[継続フレーム]]なら、
== [23] [VAR[不完全なメッセージ]]が無いなら、
[[WebSocket接続失敗]]を実行し停止するべきと思われます。
== [24] [VAR[不完全なメッセージ]]の [[payloadデータ]]に[[フレーム]]の[[payloadデータ]]を連結します。
[[拡張]]により規定がある場合は、その方法によります [SRC[>>54]]。
= [25] [[テキストフレーム]]か[[バイナリーフレーム]]なら、
== [26] [VAR[不完全なメッセージ]]があるなら、
[[WebSocket接続失敗]]を実行し停止するべきと思われます。
== [27] [VAR[不完全なメッセージ]]を、本[[フレーム]]に設定します。
= [28] [[フレーム]]の[CODE[[[FIN]]]] が [CODE[[[1]]]] なら、
== [29] [VAR[不完全なメッセージ]]の[[payloadデータ]]を[[拡張]]の規定 (あれば) により処理します [SRC[>>54]]。
== [30] [VAR[不完全なメッセージ]]が[[テキストフレーム]]なら、
=== [31] [[応用データ]]を [[UTF-8]] として[[復号]]します。
=== [32] [[復号]]に失敗したら、[[WebSocket接続失敗]]を実行し、停止します [SRC[>>21]]。
== [56] [DFN[[RUBYB[WebSocketメッセージを受信]@en[A WebSocket Message Has Been Received]]]]を実行します。[[テキストフレーム]]なら[[復号]]した[[文字列]]を、[[バイナリーフレーム]]なら[[応用データ]]を引き渡します。 [SRC[>>54]]
== [33] [VAR[不完全なメッセージ]]を、 [[null]] に設定します。
]FIG]
;; [20] [[RFC]] はエラー処理を曖昧にしか規定していません。 ([[IETF]] ではよくあることです。)
;; [35] [[RFC]] は閉じ方が規定毎に違う説明になっていますが、何か意図的なのか、
すべて[[WebSocket接続失敗]]と同じとみなして良いのか不明です。
[52] 扱える[[フレーム]]のサイズや[[断片化]]を結合した[[メッセージ]]のサイズに上限がある実装は、
それを超えないよう自身を保護しなければ[['''なりません''']] [SRC[>>50]]。
[2] [[利用者エージェント]]は、[[WebSocketメッセージを受信]]したら、
次の[[タスク]]を[[タスクキュー]]に追加しなければ[['''なりません''']] [SRC[>>1]]。
[FIG(list members)[
[FIGCAPTION[
[[タスク]]
]FIGCAPTION]
:[[タスク源]]:[[WebSocketタスク源]]
:処理:
[FIG(steps)[
= [CODE(DOMa)@en[[[readyState]]]] が [CODE(DOM)[[[OPEN]]]] ([CODE[[[1]]]])
でなければ、停止します。
= 受信したデータが[[テキスト]]なら、
== [VAR[data]] を、受信したデータに設定します。
= 受信したデータが[[バイナリー]]なら、
== [CODE(DOMa)@en[[[binaryType]]]] が [CODE[[[blob]]]] なら、
=== [VAR[data]] を、生データが受信したデータである新しい
[CODE(DOMi)@en[[[Blob]]]] に設定します。
== [CODE(DOMa)@en[[[binaryType]]]] が [CODE[[[arraybuffer]]]] なら、
=== [VAR[data]] を、生データが受信したデータを内容として持つ新しい
[CODE(DOMi)@en[[[Blob]]]] に設定します。
= [[イベント]]を[[発火]]します。
[FIG(list members short)[
[FIGCAPTION[
[[イベント]]
]FIGCAPTION]
:[[インターフェイス]]:[CODE(DOMi)@en[[[MessageEvent]]]]
:[[イベント型]]:[CODE(DOMe)@en[[[message]]]]
:[[イベント対象]]:[CODE(DOMi)@en[[[WebSocket]]]] [[オブジェクト]]
:[[trusted]]:[[真]]
:[[bubbles]]:[[偽]]
:[[取り消し可能]]:[[偽]]
:[[既定動作]]:なし
:[CODE(DOMa)@en[[[origin]]]]:[COCDE(DOMi)@en[[[WebSocket]]]] の [CODE(DOMa)@en[[[url]]]]
の[[URLの起源]]の[[Unicode直列化]]
:[CODE(DOMa)@en[[[data]]]]:[VAR[data]]
]FIG]
]FIG]
]FIG]
[3] [[利用者エージェント]]は、本[[タスク]]の実行の時に効率的に実行する条件が満たされていなければ、実行を遅延させて他の[[タスクキュー]]の[[タスク]]を実行することが[RUBYB[推奨]@en[encouraged]]されています。 [SRC[>>1]]
[EG[
[4] 例えば、受信したデータが[[ディスク]]にあり、[[タスク]]実行時点で
[CODE(DOMa)@en[[[binaryType]]]] が [CODE[[[arraybuffer]]]] になっていれば、
データを[[メモリー]]に読み込む処理を実行し、その完了まで他の[[タスク]]を実行していることができます。 [SRC[>>1]]
]EG]
[34] [[サーバー]]は、[[WebSocketメッセージを受信]]したら、適宜必要な処理を実行できます。