<html xmlns="http://www.w3.org/1999/xhtml"><head></head><body><section><h1>仕様書</h1><refs xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:"><ul xmlns="http://www.w3.org/1999/xhtml"><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="1" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[1]</anchor-end> <strong><cite xml:lang="en">RFC 6455 - The WebSocket Protocol</cite> (<time>2015-03-11 20:42:50 +09:00</time> 版) <anchor-external xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:resScheme="URI" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:resParameter="http://tools.ietf.org/html/rfc6455#section-5.5.2">http://tools.ietf.org/html/rfc6455#section-5.5.2</anchor-external></strong></li><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="7" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[7]</anchor-end> <cite xml:lang="en-GB-x-hixie">HTML Standard</cite> (<time>2015-05-06 10:42:35 +09:00</time> 版) <anchor-external xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:resScheme="URI" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:resParameter="https://html.spec.whatwg.org/#ping-and-pong-frames">https://html.spec.whatwg.org/#ping-and-pong-frames</anchor-external></li></ul></refs></section><section><h1>構文</h1><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="2" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[2]</anchor-end> <code><anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">opcode</anchor></code> は、 <code><anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">0x9</anchor></code> です <src xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:10:"><anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="1" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;1</anchor-internal></src>。
<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">Pingフレーム</anchor>は、<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">制御フレーム</anchor>です。</p><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="3" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[3]</anchor-end> <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">応用データ</anchor>を含めて構いません <src xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:10:"><anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="1" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;1</anchor-internal></src>。
<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">応用データ</anchor>は特に規定がなく、任意のバイト列で良いようです。
ただし<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">制御フレーム</anchor>の長さ制限から、125バイト以下でなければなりません。</p></section><section><h1>文脈</h1><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="5" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[5]</anchor-end> <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">WebSocket接続の確立</anchor>の後、任意の時機に送信できます <src xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:10:"><anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="1" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;1</anchor-internal></src>。</p><comment-p xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:10:"><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="6" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[6]</anchor-end> <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">keepalive</anchor> としても、相手がまだ反応するか検証する手段としても使えます <src><anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="1" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;1</anchor-internal></src>。</comment-p><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="8" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[8]</anchor-end> <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">利用者エージェント</anchor>は、必要に応じて (<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">NAT</anchor> に<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">接続</anchor>を保持させるため、
<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">接続</anchor>の切断を検出するためなどの目的で) <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">Pingフレーム</anchor>を送信して構いません <src xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:10:"><anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="7" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;7</anchor-internal></src>。
しかし<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">サーバー</anchor>を助ける目的で送信しては<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:"><strong xmlns="http://www.w3.org/1999/xhtml">なりません</strong></anchor> <src xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:10:"><anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="7" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;7</anchor-internal></src>。</p><comment-p xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:10:"><anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">サーバー</anchor>は必要があるなら自身で適宜送信するべきです。</comment-p><comment-p xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:10:"><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="9" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[9]</anchor-end> これは <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">fingerprinting vector</anchor> かもしれません。</comment-p><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="16" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[16]</anchor-end> <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">Chrome</anchor> も <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">Firefox</anchor> も、(少なくても数時間以内には)
<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">Pingフレーム</anchor>や<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">Pongフレーム</anchor>を自発的に送信することはないようです。
<time>2015-08-17T02:36:51.100Z</time></p><comment-p xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:10:"><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="17" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[17]</anchor-end> <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">Firefox</anchor> は送信・設定できるようにしたようですが <src><anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="12" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;12</anchor-internal></src>、
その後 <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">TCP keep alive</anchor> が実装されたことで使われなくなったと思われます。</comment-p></section><section><h1>処理</h1><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="4" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[4]</anchor-end> <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">Pingフレーム</anchor>を受信したら、既に <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:"><code xmlns="http://www.w3.org/1999/xhtml">Close</code>フレーム</anchor>を受信した場合を除き、
<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:"><code xmlns="http://www.w3.org/1999/xhtml">Pong</code>フレーム</anchor>を送信しなければ<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:"><strong xmlns="http://www.w3.org/1999/xhtml">なりません</strong></anchor>。
これはできるだけすぐに送信する<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:"><strong xmlns="http://www.w3.org/1999/xhtml">べきです</strong></anchor>。 <src xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:10:"><anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="1" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;1</anchor-internal></src>
<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">応用データ</anchor>を返送しなければなりません。
複数受信した場合は、最後のものにのみ返信することとしても構いません。</p><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="11" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[11]</anchor-end> <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">Chrome</anchor> も <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">Firefox</anchor> も、すべてに順に返信しているように見えます。 <time>2015-08-16T14:59:12.400Z</time></p><hr></hr><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="21" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[21]</anchor-end> <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">Webブラウザー</anchor>の <code>WebSocket</code> <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">API</anchor> は <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">Pingフレーム</anchor>や
<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">Pongフレーム</anchor>を扱う手段を一切提供していません。 <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">JavaScript</anchor>
側で扱うべきものではなく、<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">プロトコル</anchor>の内部処理に過ぎないと考えられています。</p><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="22" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[22]</anchor-end> <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">Webサーバー</anchor>側の <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">API</anchor> や、<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">Webブラウザー</anchor>以外の<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">クライアント</anchor>の
<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">API</anchor> は、 <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">Pingフレーム</anchor>や <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">Pongフレーム</anchor>を扱う手段を提供できます。
しかし<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">アプリケーション</anchor>のデータはすべて<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">テキストフレーム</anchor>や<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">バイナリーフレーム</anchor>で送受信するべきで、
<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">Pingフレーム</anchor>や<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">Pongフレーム</anchor>が<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">アプリケーション</anchor>の処理に影響するべきではありません。</p></section><section><h1>関連</h1><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="10" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[10]</anchor-end> <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">HTTP/2</anchor> では <code><anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">PING</anchor></code> <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">フレーム</anchor> (<code><anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">ACK</anchor></code> 未設定)
に相当します。</p></section><section><h1>歴史</h1><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="12" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[12]</anchor-end> <cite xml:lang="en">855906 – Set pingInterval on websocket</cite>
(<time>2015-08-17 00:37:36 +09:00</time> 版)
<anchor-external xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:resScheme="URI" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:resParameter="https://bugzilla.mozilla.org/show_bug.cgi?id=855906">https://bugzilla.mozilla.org/show_bug.cgi?id=855906</anchor-external></p><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="13" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[13]</anchor-end> <cite xml:lang="en">849364 – Provide per-websocket way to enable keepalive pings</cite>
(<time>2015-08-17 00:38:16 +09:00</time> 版)
<anchor-external xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:resScheme="URI" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:resParameter="https://bugzilla.mozilla.org/show_bug.cgi?id=849364">https://bugzilla.mozilla.org/show_bug.cgi?id=849364</anchor-external></p><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="14" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[14]</anchor-end> <cite xml:lang="en">894879 – SimplePush: Adaptive ping for WebSocket</cite>
(<time>2015-08-17 00:39:40 +09:00</time> 版)
<anchor-external xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:resScheme="URI" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:resParameter="https://bugzilla.mozilla.org/show_bug.cgi?id=894879">https://bugzilla.mozilla.org/show_bug.cgi?id=894879</anchor-external></p><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="15" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[15]</anchor-end> <cite xml:lang="en">13104 – Enable keepalive on WebSocket API</cite>
(<time>2015-08-17 01:02:33 +09:00</time> 版)
<anchor-external xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:resScheme="URI" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:resParameter="https://www.w3.org/Bugs/Public/show_bug.cgi?id=13104">https://www.w3.org/Bugs/Public/show_bug.cgi?id=13104</anchor-external></p><figure class="quote"><figcaption><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="18" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[18]</anchor-end> <cite>Bitfinex API Reference</cite>
(<time>2016-05-12 07:24:33 +09:00</time>)
<anchor-external xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:resScheme="URI" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:resParameter="http://docs.bitfinex.com/#info-messages">http://docs.bitfinex.com/#info-messages</anchor-external></figcaption><blockquote><p>Ping/Pong</p><p>// request</p><p>{</p><p>&quot;event&quot;:&quot;ping&quot;</p><p>}</p><p>// response</p><p>{</p><p>&quot;event&quot;:&quot;pong&quot;</p><p>}</p><p>Use ping message to test your connection to the websocket server.</p></blockquote></figure><figure class="quote"><figcaption><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="19" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[19]</anchor-end> <cite>Bitfinex API Reference</cite>
(<time>2016-05-12 07:24:33 +09:00</time>)
<anchor-external xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:resScheme="URI" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:resParameter="http://docs.bitfinex.com/#heartbeating">http://docs.bitfinex.com/#heartbeating</anchor-external></figcaption><blockquote><p>Heartbeating</p><p><strong>[</strong>&quot;&lt;Chan Id&gt;&quot;, &quot;hb&quot;<strong>]</strong></p><p>If there is no new message in the channel for 1 second, Websocket server will send you an heartbeat message in this format.</p></blockquote></figure><figure class="quote"><figcaption><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="20" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[20]</anchor-end> <cite xml:lang="en">RFC 7977 - The WebSocket Protocol as a Transport for the Message Session Relay Protocol (MSRP)</cite>
(<time>2016-10-04 23:50:28 +09:00</time>)
<anchor-external xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:resScheme="URI" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:resParameter="https://tools.ietf.org/html/rfc7977#section-6">https://tools.ietf.org/html/rfc7977#section-6</anchor-external></figcaption><blockquote><p>It is RECOMMENDED that MSRP WebSocket Clients and Servers keep their</p><p>WebSocket connections open by sending periodic WebSocket &quot;Ping&quot;</p><p>frames as described in Section 5.5.2 of <strong>[</strong>RFC6455<strong>]</strong>.</p><p>The WebSocket API <strong>[</strong>WS-API<strong>]</strong> does not provide a mechanism for</p><p>applications running in a web browser to control whether or not</p><p>periodic WebSocket &quot;Ping&quot; frames are sent to the server.  The</p><p>implementation of such a keepalive feature is the decision of each</p><p>web browser manufacturer and may also depend on the configuration of</p><p>the web browser.</p><p>A future WebSocket protocol extension providing a similar keepalive</p><p>mechanism could also be used.</p><p>When MSRP WebSocket Clients or Servers cannot use WebSocket &quot;Ping&quot;</p><p>frames to keep connections open, an MSRP implementation MAY use</p><p>bodiless SEND requests as described in Section 7.1 of <strong>[</strong>RFC4975<strong>]</strong>.</p><p>MSRP WebSocket Clients or Servers MUST be prepared to receive</p><p>bodiless SEND requests.</p></blockquote></figure><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="23" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[23]</anchor-end> <cite xml:lang="ja">机「9」文字事件 - Wikipedia</cite>
(<time>2019-08-03 17:57:45 +09:00</time>)
<anchor-external xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:resScheme="URI" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:resParameter="https://ja.wikipedia.org/wiki/%E6%9C%BA%E3%80%8C9%E3%80%8D%E6%96%87%E5%AD%97%E4%BA%8B%E4%BB%B6">https://ja.wikipedia.org/wiki/%E6%9C%BA%E3%80%8C9%E3%80%8D%E6%96%87%E5%AD%97%E4%BA%8B%E4%BB%B6</anchor-external></p></section></body></html>