aboutsummaryrefslogtreecommitdiff
path: root/files/ja/web/api/websockets_api
diff options
context:
space:
mode:
authorPeter Bengtsson <mail@peterbe.com>2020-12-08 14:40:17 -0500
committerPeter Bengtsson <mail@peterbe.com>2020-12-08 14:40:17 -0500
commit33058f2b292b3a581333bdfb21b8f671898c5060 (patch)
tree51c3e392513ec574331b2d3f85c394445ea803c6 /files/ja/web/api/websockets_api
parent8b66d724f7caf0157093fb09cfec8fbd0c6ad50a (diff)
downloadtranslated-content-33058f2b292b3a581333bdfb21b8f671898c5060.tar.gz
translated-content-33058f2b292b3a581333bdfb21b8f671898c5060.tar.bz2
translated-content-33058f2b292b3a581333bdfb21b8f671898c5060.zip
initial commit
Diffstat (limited to 'files/ja/web/api/websockets_api')
-rw-r--r--files/ja/web/api/websockets_api/index.html113
-rw-r--r--files/ja/web/api/websockets_api/websockets_reference/index.html22
-rw-r--r--files/ja/web/api/websockets_api/writing_a_websocket_server_in_java/index.html221
-rw-r--r--files/ja/web/api/websockets_api/writing_websocket_client_applications/index.html183
-rw-r--r--files/ja/web/api/websockets_api/writing_websocket_server/index.html273
-rw-r--r--files/ja/web/api/websockets_api/writing_websocket_servers/index.html242
6 files changed, 1054 insertions, 0 deletions
diff --git a/files/ja/web/api/websockets_api/index.html b/files/ja/web/api/websockets_api/index.html
new file mode 100644
index 0000000000..9e118ad574
--- /dev/null
+++ b/files/ja/web/api/websockets_api/index.html
@@ -0,0 +1,113 @@
+---
+title: WebSocket API (WebSockets)
+slug: Web/API/WebSockets_API
+tags:
+ - API
+ - Client
+ - Communication
+ - Overview
+ - Server
+ - Two-Way
+ - WebSocket
+ - WebSocket API
+ - WebSockets
+ - data
+ - interactive
+translation_of: Web/API/WebSockets_API
+---
+<p>{{DefaultAPISidebar("Websockets API")}}</p>
+
+<p><strong>WebSocket API</strong> は、ユーザーのブラウザーとサーバー間で対話的な通信セッションを開くことができる先進技術です。この API によって、サーバーにメッセージを送信したり、応答をサーバーにポーリングすることなく、イベント駆動型のレスポンスを受信したりすることができます。</p>
+
+<div class="blockIndicator note">
+<p><strong>メモ:</strong> WebSocket のコネクションは機能的にどこか標準 Unix スタイルのソケットに似ていますが、関連はありません。</p>
+</div>
+
+<h2 id="Interfaces" name="Interfaces">インターフェイス</h2>
+
+<dl>
+ <dt><a href="/ja/docs/Web/API/WebSocket"><code>WebSocket</code></a></dt>
+ <dd>WebSocket サーバに接続し、その接続を通じてデータを送受信するための主要インターフェイス</dd>
+ <dt><code><a href="/ja/docs/Web/API/CloseEvent">CloseEvent</a></code></dt>
+ <dd>接続が閉じた時に WebSocket オブジェクトによって送信されるイベントです。</dd>
+ <dt><a href="/ja/docs/Web/API/MessageEvent"><code>MessageEvent</code></a></dt>
+ <dd>サーバーからメッセージを受信した時に WebSocket オブジェクトによって送信されるイベント</dd>
+</dl>
+
+<h2 id="Guides" name="Guides">ガイド</h2>
+
+<ul>
+ <li><a href="/ja/docs/Web/API/WebSockets_API/Writing_WebSocket_client_applications">WebSocket クライアントアプリケーションを書く</a></li>
+ <li><a href="/ja/docs/Web/API/WebSockets_API/Writing_WebSocket_servers">WebSocket サーバーを書く</a></li>
+ <li><a href="/ja/docs/Web/API/WebSockets_API/Writing_WebSocket_server">WebSocket サーバーを C# で書く</a></li>
+ <li><a href="/ja/docs/Web/API/WebSockets_API/Writing_a_WebSocket_server_in_Java">WebSocket サーバーを Java で書く</a></li>
+</ul>
+
+<h2 id="Tools" name="Tools">ツール</h2>
+
+<ul>
+ <li><a href="https://hacks.mozilla.org/2017/06/introducing-humblenet-a-cross-platform-networking-library-that-works-in-the-browser/">HumbleNet</a>: ブラウザーで動作するクロスプラットフォームのネットワークライブラリです。ブラウザー間の違いを抽象化する WebSocket や WebRTC の C ラッパー、ゲームやその他のアプリで複数ユーザーのネットワーク機能を作成するものから成ります。</li>
+ <li><a href="https://github.com/uWebSockets/uWebSockets">µWebSockets</a>: <a href="https://isocpp.org/">C++11</a> および <a href="https://nodejs.org">Node.js</a> で書かれた可用性の高い WebSocket サーバーとクライアントの実装です。</li>
+ <li><a href="https://github.com/ClusterWS/ClusterWS">ClusterWS</a>: <a href="https://nodejs.org">Node.js</a> でスケーラブルな WebSocket アプリケーションを構築する、軽量で高速で強力なフレームワークです。</li>
+ <li><a href="https://github.com/ClusterWS/cWS">CWS</a>: Node.js のための高速な C++ による WebSocket の実装です (uWebSockets v0.14 のフォーク)</li>
+ <li><a class="external" href="https://socket.io">Socket.IO</a>: 長いポーリングと WevSocket ベースのサードバーティ―の <a href="https://nodejs.org">Node.js</a> 用転送プロトコルです。</li>
+ <li><a href="http://socketcluster.io/">SocketCluster</a>: スケーラビリティに焦点を当てた <a href="https://nodejs.org">Node.js</a> 用の pub/sub WebSocket フレームワークです。</li>
+ <li><a class="link-https" href="https://github.com/Worlize/WebSocket-Node">WebSocket-Node</a>: <a href="https://nodejs.org">Node.js</a> 用の WebSocket サーバー API 実装です。</li>
+ <li><a href="http://www.totaljs.com">Total.js</a>: <a href="https://www.nodejs.org">Node.js</a> 用の ウェブアプリケーションフレームワーク(使用例: <a href="https://github.com/totaljs/examples/tree/master/websocket">WebSocket chat</a>)</li>
+ <li><a href="https://www.npmjs.com/package/faye-websocket">Faye</a>: <a href="https://nodejs.org">Node.js</a> 用の <a href="/ja/docs/Web/API/WebSockets_API">WebSocket</a> (双方向接続) と <a href="/ja/docs/Web/API/EventSource/">EventSource</a> (片方向接続) サーバーおよびクライアント</li>
+ <li><a href="http://signalr.net/">SignalR</a>: SignalR は単一のコードだけで、もし WebSockets が使用可能な場合、基盤として WebSockets を使用し、そうでない場合はほかの代替技術にフォールバックします。</li>
+ <li><a href="https://caddyserver.com/docs/websocket">Caddy</a>: WebSocket として任意のコマンド (stdin/stdout) を中継することができるウェブサーバーです。</li>
+ <li><a href="https://github.com/websockets/ws">ws</a>: <a href="https://nodejs.org/">Node.js</a> のための有名な WebSocket クライアント&サーバーライブラリです。</li>
+ <li><a href="https://github.com/bigstepinc/jsonrpc-bidirectional">jsonrpc-bidirectional</a>: 非同期の RPC で、単一の接続を用いて、サーバー上にエクスポートされた機能と、同時にクライアント上のものがあります (クライアントがサーバーを呼び出すことができ、サーバーもクライアントを呼び出すことができます)。</li>
+ <li><a href="https://github.com/ninenines/cowboy">cowboy</a>: Cowboy は高速で最新の HTTP サーバーで、 Erlang/OTP のためのものであり、 WebSocket に対応しています。</li>
+</ul>
+
+<h2 class="Related_Topics" id="Related_Topics" name="Related_Topics">関連トピック</h2>
+
+<ul>
+ <li><a href="/ja/docs/Web/Guide/AJAX">AJAX</a></li>
+ <li><a href="/ja/docs/Web/JavaScript">JavaScript</a></li>
+</ul>
+
+<h2 id="Specifications" name="Specifications">仕様書</h2>
+
+<table class="standard-table">
+ <thead>
+ <tr>
+ <th scope="col">仕様書</th>
+ <th scope="col">状態</th>
+ <th scope="col">備考</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td>{{SpecName("HTML WHATWG", "web-sockets.html", "WebSocket API")}}</td>
+ <td>{{Spec2("HTML WHATWG")}}</td>
+ <td></td>
+ </tr>
+ <tr>
+ <td><a href="https://www.w3.org/TR/websockets/">WebSockets</a></td>
+ <td><span class="spec-CR">Candidate Recommendation</span></td>
+ <td></td>
+ </tr>
+ <tr>
+ <td>{{RFC(6455, "The WebSocket Protocol")}}</td>
+ <td><span class="spec-RFC">IETF RFC</span></td>
+ <td></td>
+ </tr>
+ </tbody>
+</table>
+
+<h2 id="Browser_compatibility" name="Browser_compatibility">ブラウザーの互換性</h2>
+
+<div class="hidden">このページの互換性一覧表は構造化データから生成されています。データに協力していただけるのであれば、 <a class="external" href="https://github.com/mdn/browser-compat-data">https://github.com/mdn/browser-compat-data</a> をチェックアウトしてプルリクエストを送信してください。</div>
+
+<p>{{Compat("api.WebSocket")}}</p>
+
+<h2 id="See_also" name="See_also">関連情報</h2>
+
+<ul>
+ <li><a class="external" href="http://tools.ietf.org/html/rfc6455">RFC 6455 — The WebSocket Protocol</a></li>
+ <li><a class="external" href="https://www.w3.org/TR/websockets/">WebSocket API 仕様書</a></li>
+ <li><a href="/ja/docs/Server-sent_events">Server-Sent イベント</a></li>
+</ul>
diff --git a/files/ja/web/api/websockets_api/websockets_reference/index.html b/files/ja/web/api/websockets_api/websockets_reference/index.html
new file mode 100644
index 0000000000..85b5acc880
--- /dev/null
+++ b/files/ja/web/api/websockets_api/websockets_reference/index.html
@@ -0,0 +1,22 @@
+---
+title: WebSockets リファレンス
+slug: Web/API/WebSockets_API/WebSockets_reference
+tags:
+ - WebSocket
+ - WebSockets
+translation_of: Web/API/WebSockets_API
+---
+<div>{{draft}}</div>
+<p>以下のページは、WebSocket API のインタフェースに関する文書です。</p>
+
+
+<dl>
+ <dt><a href="/ja/docs/WebSockets/WebSockets_reference/WebSocket"><code>WebSocket</code></a></dt>
+ <dd>WebSocket のサーバに接続し、その接続上でデータを送受信するためのプライマリインターフェイス</dd>
+
+ <dt><a href="/ja/docs/WebSockets/WebSockets_reference/CloseEvent"><code>CloseEvent</code></a></dt>
+ <dd>接続を閉じる際に <code>WebSocket</code> オブジェクトによって送信されるイベント</dd>
+
+ <dt><a href="/ja/docs/WebSockets/WebSockets_reference/MessageEvent"><code>MessageEvent</code></a></dt>
+ <dd>サーバからのメッセージの受信時に <code>Websocket</code> オブジェクトによって送出されるイベント</dd>
+</dl>
diff --git a/files/ja/web/api/websockets_api/writing_a_websocket_server_in_java/index.html b/files/ja/web/api/websockets_api/writing_a_websocket_server_in_java/index.html
new file mode 100644
index 0000000000..a1d1fc553a
--- /dev/null
+++ b/files/ja/web/api/websockets_api/writing_a_websocket_server_in_java/index.html
@@ -0,0 +1,221 @@
+---
+title: Java で WebSocket サーバを記述する
+slug: Web/API/WebSockets_API/Writing_a_WebSocket_server_in_Java
+tags:
+ - HTML5
+ - NeedsMarkupWork
+ - WebSockets
+ - チュートリアル
+ - ハンドシェイキング
+translation_of: Web/API/WebSockets_API/Writing_a_WebSocket_server_in_Java
+---
+<h2 id="イントロダクション">イントロダクション</h2>
+
+<p>この例では、Oracle Java を使用して WebSocket API サーバーを作成する方法を示します。<br>
+ <br>
+ 他のサーバーサイドの言語を使用して WebSocket サーバーを作成することもできますが、この例では Oracle Java を使用してサンプルコードを簡略化しています。</p>
+
+<p>このサーバーは <a href="http://tools.ietf.org/html/rfc6455">RFC 6455</a> に準拠しているため、Chrome バージョン 16、Firefox 11、IE 10 以降の接続のみを処理します。</p>
+
+<h2 id="ファーストステップ">ファーストステップ</h2>
+
+<p>WebSocket は <a href="http://en.wikipedia.org/wiki/Transmission_Control_Protocol">TCP (伝送制御プロトコル)</a> 接続を介して通信します。 Java の <a href="https://docs.oracle.com/javase/jp/8/docs/api/java/net/ServerSocket.html">ServerSocket</a> クラスは java.net パッケージにあります。</p>
+
+<h3 id="ServerSocket">ServerSocket</h3>
+
+<p>コンストラクタ:</p>
+
+<pre class="brush: java"><code><span class="memberNameLink">ServerSocket</span>(int port)</code></pre>
+
+<p>ServerSocket クラスをインスタンス化すると、port 引数で指定したポート番号にバインドされます。</p>
+
+<p><span style="line-height: 1.572;">私たちが学んだことを実装する方法は次のとおりです。</span></p>
+
+<pre class="brush: java">import java.net.ServerSocket;
+import java.net.Socket;
+
+public class Server{
+ public static void main(String[] args){
+ ServerSocket server = new ServerSocket(80);
+
+ System.out.println("Server has started on 127.0.0.1:80.\r\nWaiting for a connection...");
+
+ Socket client = server.accept();
+
+ System.out.println("A client connected.");
+ }
+}</pre>
+
+<h3 id="Socket">Socket</h3>
+
+<p>メソッド:</p>
+
+<ul>
+ <li><code>java.net.</code><a href="https://docs.oracle.com/javase/jp/8/docs/api/java/net/Socket.html" title="class in java.net">Socket</a><code> <span class="memberNameLink"><a href="https://docs.oracle.com/javase/jp/8/docs/api/java/net/Socket.html#getInputStream--">getInputStream</a></span>()</code><br>
+ このソケットの入力ストリームを返します。</li>
+ <li><code>java.net.</code><a href="https://docs.oracle.com/javase/jp/8/docs/api/java/net/Socket.html" title="class in java.net">Socket</a><code> <span class="memberNameLink"><a href="https://docs.oracle.com/javase/jp/8/docs/api/java/net/Socket.html#getOutputStream--">getOutputStream</a></span>()</code><br>
+ このソケットの出力ストリームを返します。</li>
+</ul>
+
+<h3 id="OutputStream">OutputStream</h3>
+
+<p>メソッド:</p>
+
+<pre class="brush: java">write<code>(byte[] b, int off, int len)</code></pre>
+
+<p>指定された byte 配列からオフセット <em><code>off</code></em> で始まる <em><code>len</code></em> バイトをこの出力ストリームに書き込みます。</p>
+
+<h3 id="InputStream">InputStream</h3>
+
+<p>メソッド:</p>
+
+<pre class="brush: java"><span class="brush: cpp" style="line-height: 1.572;">read</span><code>(byte[] b, int off, int len)</code></pre>
+
+<p>最大 len バイトのデータを入力ストリームからバイト配列に読み込みます。<em> </em></p>
+
+<p>私たちの例を拡張してみましょう。</p>
+
+<pre class="brush: java">Socket client = server.accept();
+
+System.out.println("A client connected.");
+
+InputStream in = client.getInputStream();
+
+OutputStream out = client.getOutputStream();
+
+new Scanner(in, "UTF-8").useDelimiter("\\r\\n\\r\\n").next();</pre>
+
+<h2 id="ハンドシェイキング">ハンドシェイキング</h2>
+
+<p>クライアントがサーバーに接続すると、単純な HTTP リクエストから WebSocket への接続をアップグレードするための GET リクエストが送信されます。 これはハンドシェイキングと呼ばれます。</p>
+
+<pre class="brush: java">import java.util.Scanner;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+//translate bytes of request to string
+String data = new Scanner(in,"UTF-8").useDelimiter("\\r\\n\\r\\n").next();
+
+Matcher get = Pattern.compile("^GET").matcher(data);
+
+if (get.find()) {
+
+} else {
+
+}</pre>
+
+<p>このようにしなければならない理由を理解するよりも、レスポンスを作成する方が簡単です。</p>
+
+<p>次のことをやらなければなりません</p>
+
+<ol>
+ <li>先頭と末尾の空白なしで Sec-WebSocket-Key リクエストヘッダーの値を取得します</li>
+ <li>"258EAFA5-E914-47DA-95CA-C5AB0DC85B11" とリンクします</li>
+ <li>SHA-1 と Base64 のコードを計算します</li>
+ <li>Sec-WebSocket-Accept レスポンスヘッダーの値を HTTP レスポンスの一部として書き戻します。</li>
+</ol>
+
+<pre class="brush: java">if (get.find()) {
+ Matcher match = Pattern.compile("Sec-WebSocket-Key: (.*)").matcher(data);
+ match.find();
+ byte[] response = ("HTTP/1.1 101 Switching Protocols\r\n"
+ + "Connection: Upgrade\r\n"
+ + "Upgrade: websocket\r\n"
+ + "Sec-WebSocket-Accept: "
+ + DatatypeConverter
+ .printBase64Binary(
+ MessageDigest
+ .getInstance("SHA-1")
+ .digest((match.group(1) + "258EAFA5-E914-47DA-95CA-C5AB0DC85B11")
+ .getBytes("UTF-8")))
+ + "\r\n\r\n")
+ .getBytes("UTF-8");
+
+ out.write(response, 0, response.length);
+}
+</pre>
+
+<h2 id="メッセージのデコード">メッセージのデコード</h2>
+
+<p>ハンドシェイクが成功した後、クライアントはサーバーにメッセージを送信できますが、これはエンコードされています。</p>
+
+<p>"abcdef" を送信すると、次のバイトが得られます。</p>
+
+<table>
+ <tbody>
+ <tr>
+ <td>129</td>
+ <td>134</td>
+ <td>167</td>
+ <td>225</td>
+ <td>225</td>
+ <td>210</td>
+ <td>198</td>
+ <td>131</td>
+ <td>130</td>
+ <td>182</td>
+ <td>194</td>
+ <td>135</td>
+ </tr>
+ </tbody>
+</table>
+
+<p>- 129:</p>
+
+<table>
+ <thead>
+ <tr>
+ <th scope="col">FIN (これは全体のメッセージですか?)</th>
+ <th scope="col">RSV1</th>
+ <th scope="col">RSV2</th>
+ <th scope="col">RSV3</th>
+ <th scope="col">Opcode</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td>1</td>
+ <td>0</td>
+ <td>0</td>
+ <td>0</td>
+ <td>0x1=0001</td>
+ </tr>
+ </tbody>
+</table>
+
+<p>FIN: あなたはメッセージをフレームで送ることができますが、今は物事を単純に保ちます。<br>
+ Opcode<span style="line-height: 1.572;"> 0x1 は、これがテキストであることを意味します。<a href="http://tools.ietf.org/html/rfc6455#section-5.2">オペコードの完全なリスト</a>です</span></p>
+
+<p>- 134:</p>
+
+<p>2番目のバイトから 128 を引いた値が 0〜125 の場合、これはメッセージの長さです。126 の場合は、次の 2 バイト (16 ビット符号なし整数)、127 の場合、次の 8 バイト (64 ビット符号なし整数、最上位ビットは 0 でなければならない) が長さです。</p>
+
+<div class="note">
+<p>最初のビットは常に1なので、128を取ることができます。</p>
+</div>
+
+<p>- 167、225、225、および 210 はデコードするキーのバイトです。それは毎回変わります。</p>
+
+<p>- 残りの符号化されたバイトはメッセージです。</p>
+
+<h3 id="アルゴリズムのデコード">アルゴリズムのデコード</h3>
+
+<p>デコードされたバイト = エンコードされたバイト XOR (エンコードされたバイトの位置 BITWISE および 0x3) バイト目のキー</p>
+
+<p>Java の例です</p>
+
+<pre class="brush: java">byte[] decoded = new byte[6];
+byte[] encoded = new byte[] {198, 131, 130, 182, 194, 135};
+byte[] key = byte[4] {167, 225, 225, 210};
+
+for (int i = 0; i &lt; encoded.length; i++) {
+ decoded[i] = (byte)(encoded[i] ^ key[i &amp; 0x3]);
+}</pre>
+
+<h2 id="関連">関連</h2>
+
+<ul>
+ <li><a href="/ja/docs/WebSockets-840092-dup/Writing_WebSocket_servers">Writing WebSocket servers</a></li>
+</ul>
+
+<div id="cke_pastebin" style="position: absolute; top: 2209.23px; width: 1px; height: 1px; overflow: hidden; left: -1000px;"> </div>
diff --git a/files/ja/web/api/websockets_api/writing_websocket_client_applications/index.html b/files/ja/web/api/websockets_api/writing_websocket_client_applications/index.html
new file mode 100644
index 0000000000..b9111abfe8
--- /dev/null
+++ b/files/ja/web/api/websockets_api/writing_websocket_client_applications/index.html
@@ -0,0 +1,183 @@
+---
+title: WebSocket クライアントアプリケーションの記述
+slug: Web/API/WebSockets_API/Writing_WebSocket_client_applications
+tags:
+ - Client
+ - Example
+ - Guide
+ - Networking
+ - Web Sockets API
+ - WebSocket
+ - WebSocket API
+ - WebSockets
+ - ガイド
+ - ネットワーク
+ - 例
+translation_of: Web/API/WebSockets_API/Writing_WebSocket_client_applications
+---
+<div>{{APIRef("Websockets API")}}</div>
+
+<p>WebSocket クライアントアプリケーションは <a href="/ja/docs/Web/API/Websockets_API">WebSocket API</a> を使用して、 WebSocket プロトコルを経由して <a href="/ja/docs/Web/API/WebSockets_API/Writing_WebSocket_servers">WebSocket サーバー</a>と通信します。</p>
+
+<p>{{AvailableInWorkers}}</p>
+
+<div class="note">
+<p><strong>メモ:</strong> この記事のサンプルスニペットは WebSocket チャットクライアント/サーバーサンプルから取得したものです。 <a href="https://github.com/mdn/samples-server/tree/master/s/websocket-chat">コードを見て</a>から、<a href="https://mdn-samples.mozilla.org/s/websocket-chat">自分で例を試してみてください</a>。</p>
+</div>
+
+<h2 id="Creating_a_WebSocket_object" name="Creating_a_WebSocket_object">WebSocket オブジェクトの作成</h2>
+
+<p>WebSocket プロトコルを使用して通信するには、 {{domxref("WebSocket")}} オブジェクトを作成する必要があります。これにより自動的にサーバーへの接続が開かれます。</p>
+
+<p>WebSocket のコンストラクターは、必須1つ、任意1つの引数を受け取ります。</p>
+
+<pre class="syntaxbox"><em>webSocket</em> = new WebSocket(<em>url</em>, <em>protocols</em>);
+</pre>
+
+<dl>
+ <dt><code>url</code></dt>
+ <dd>接続先 URL。これは、 WebSocket サーバーが応答する URL である必要があります。これは URL スキームに <code>wss://</code> を使用するべきですが、ソフトウェアによってはローカル接続用に安全ではない <code>ws://</code> を使用することを許可していることがあります。</dd>
+ <dt><code>protocols</code> {{ optional_inline() }}</dt>
+ <dd>単一のプロトコル文字列または一連のプロトコル文字列。これらの文字列はサブプロトコルを示すのに使用されるため、単一のサーバーで複数の WebSocket サブプロトコルを実装できます (たとえば、特定の <code>protocol</code> に応じて1つのサーバーで異なるタイプのインタラクションを処理できるようにする)。プロトコル文字列を指定しない場合、空文字列であると仮定されます。</dd>
+</dl>
+
+<p>コンストラクターは、接続先がアクセスを許可していない場合に <code>SecurityError</code> 例外を発生させます。これは安全ではない接続を利用しようとしたときに発生することがあります (ほとんどの{{Glossary("user agent", "ユーザーエージェント")}}は、同じ機器か、可能であれば同じネットワークでない限り、すべての WebSocket 接続に安全なリンクを要求します。</p>
+
+<h3 id="Connection_errors" name="Connection_errors">接続エラー</h3>
+
+<p>接続中にエラーが発生した場合、最初に <code>error</code> という名前の単純なイベントが {{domxref("WebSocket")}} オブジェクトに送信され (その結果、その {{domxref("WebSocket.onerror", "onerror")}} ハンドラーが呼び出されます)、次に {{domxref("CloseEvent")}} が <code>WebSocket</code> オブジェクトに送信され ({{domxref("WebSocket.onclose", "onclose")}} ハンドラーが呼び出されます) 接続の終了の理由を示します。</p>
+
+<p>ブラウザーはコンソールにも、 <a class="external" href="http://tools.ietf.org/html/rfc6455#section-7.4" title="RFC 6455 Section 7.4">RFC 6455 の 7.4 節</a> で定義されている {{domxref("CloseEvent")}} 経由の終了コードと同時に、もっと説明的なエラーメッセージを出力することもあります。</p>
+
+<h3 id="Examples" name="Examples">例</h3>
+
+<p>この簡単な例では新しい WebSocket を作成し、 <code><span class="nowiki">wss://www.example.com/socketserver</span></code> のサーバーに接続します。この例では、ソケットの要求で "protocolOne" のカスタムプロトコルが指定されていますが、省略することもできます。</p>
+
+<pre class="brush: js">var exampleSocket = new WebSocket("wss://www.example.com/socketserver", "protocolOne");
+</pre>
+
+<p>返されると、 {{domxref("WebSocket.readyState", "exampleSocket.readyState")}} は <code>CONNECTING</code> です。 <code>readyState</code> は接続がデータを転送する準備ができたら <code>OPEN</code>になります。</p>
+
+<p>接続を開き、サポートしているプロトコルについて柔軟に対応したい場合は、プロトコルの配列を指定できます。</p>
+
+<pre class="brush: js">var exampleSocket = new WebSocket("wss://www.example.com/socketserver", ["protocolOne", "protocolTwo"]);
+</pre>
+
+<p>接続が確立されると (つまり <code>readyState</code> が <code>OPEN</code>)、 {{domxref("WebSocket.protocol", "exampleSocket.protocol")}} は、サーバーが選択したプロトコルを通知します。</p>
+
+<p>WebSocket を確立するには、<a href="/ja/docs/Web/HTTP/Protocol_upgrade_mechanism">HTTP アップグレードメカニズム</a>が必要です。したがって、 HTTP サーバーを <code><span class="nowiki">ws://www.example.com</span></code> または <code><span class="nowiki">wss://www.example.com</span></code> としてアドレス指定すると、プロトコルのアップグレード要求が暗黙的に行われます。</p>
+
+<h2 id="Sending_data_to_the_server" name="Sending_data_to_the_server">サーバーにデータを送信する</h2>
+
+<p>接続を開くと、サーバーにデータを送信することができます。 これを行うには、送信するメッセージごとに <code>WebSocket</code> オブジェクトの {{domxref("WebSocket.send", "send()")}} メソッドを呼び出します。</p>
+
+<pre class="brush: js">exampleSocket.send("Here's some text that the server is urgently awaiting!");
+</pre>
+
+<p>データを文字列、 {{ domxref("Blob") }}、 {{jsxref("ArrayBuffer")}} のいずれかとして送信することができます。</p>
+
+<p>接続の確立は非同期であり、失敗しやすいため、 <code>send()</code> メソッドの呼び出しが WebSocket オブジェクトの作成直後に成功するという保証はありません。データの送信を試みるのは、少なくともいったん接続が確立してからでなければならないので、作業を行うための {{domxref("WebSocket.onopen", "onopen")}} イベントハンドラーを定義してその中で行います。</p>
+
+<pre class="brush: js">exampleSocket.onopen = function (event) {
+ exampleSocket.send("Here's some text that the server is urgently awaiting!");
+};
+</pre>
+
+<h3 id="Using_JSON_to_transmit_objects" name="Using_JSON_to_transmit_objects">JSON を使用したオブジェクトの送信</h3>
+
+<p>サーバーに複雑なデータを合理的に送信するのに手軽な方法の一つとして、 {{glossary("JSON")}} を使用する方法があります。たとえば、チャットプログラムがサーバーとやり取りするのに、 JSON でカプセル化されたデータのパケットを使用して実装されたプロトコルを使用することができます。</p>
+
+<pre class="brush: js">// Send text to all users through the server
+function sendText() {
+ // Construct a msg object containing the data the server needs to process the message from the chat client.
+ var msg = {
+ type: "message",
+ text: document.getElementById("text").value,
+ id: clientID,
+ date: Date.now()
+ };
+
+ // Send the msg object as a JSON-formatted string.
+ exampleSocket.send(JSON.stringify(msg));
+
+ // Blank the text input element, ready to receive the next line of text from the user.
+ document.getElementById("text").value = "";
+}
+</pre>
+
+<h2 id="Receiving_messages_from_the_server" name="Receiving_messages_from_the_server">サーバーからのメッセージの受信</h2>
+
+<p>WebSockets はイベント駆動型 API です。メッセージを受信すると、 <code>message</code> イベント <code>WebSocket</code> オブジェクトに送信されます。これを処理するには、 <code>message</code> イベントのイベントリスナーを追加するか、 {{domxref("WebSocket.onmessage", "onmessage")}} イベントハンドラーを使用するかします。受信データの待ち受けを開始するには、次のようにします。</p>
+
+<pre class="brush: js">exampleSocket.onmessage = function (event) {
+ console.log(event.data);
+}
+</pre>
+
+<h3 id="Receiving_and_interpreting_JSON_objects" name="Receiving_and_interpreting_JSON_objects">JSON オブジェクトの受信と解釈</h3>
+
+<p>まず{{ anch("Using JSON to transmit objects", "JSON を使用したオブジェクトの送信") }}で述べられているチャットクライアントアプリケーションを考えてみましょう。クライアントが受信するデータパケットの種類は次のとおりです。</p>
+
+<ul>
+ <li>ログインハンドシェイク</li>
+ <li>メッセージテキスト</li>
+ <li>ユーザーリストの更新</li>
+</ul>
+
+<p>これらの受信メッセージを解釈するコードは、次のようになります。</p>
+
+<pre class="brush: js">exampleSocket.onmessage = function(event) {
+ var f = document.getElementById("chatbox").contentDocument;
+ var text = "";
+ var msg = JSON.parse(event.data);
+ var time = new Date(msg.date);
+ var timeStr = time.toLocaleTimeString();
+
+ switch(msg.type) {
+ case "id":
+ clientID = msg.id;
+ setUsername();
+ break;
+ case "username":
+ text = "&lt;b&gt;User &lt;em&gt;" + msg.name + "&lt;/em&gt; signed in at " + timeStr + "&lt;/b&gt;&lt;br&gt;";
+ break;
+ case "message":
+ text = "(" + timeStr + ") &lt;b&gt;" + msg.name + "&lt;/b&gt;: " + msg.text + "&lt;br&gt;";
+ break;
+ case "rejectusername":
+ text = "&lt;b&gt;Your username has been set to &lt;em&gt;" + msg.name + "&lt;/em&gt; because the name you chose is in use.&lt;/b&gt;&lt;br&gt;"
+ break;
+ case "userlist":
+ var ul = "";
+ for (i=0; i &lt; msg.users.length; i++) {
+ ul += msg.users[i] + "&lt;br&gt;";
+ }
+ document.getElementById("userlistbox").innerHTML = ul;
+ break;
+ }
+
+ if (text.length) {
+ f.write(text);
+ document.getElementById("chatbox").contentWindow.scrollByPages(1);
+ }
+};
+</pre>
+
+<p>ここで {{jsxref("JSON.parse()")}} を使用して JSON オブジェクトを元のオブジェクトに変換し、その内容を調べて処理します。</p>
+
+<h3 id="Text_data_format" name="Text_data_format">テキストデータ形式</h3>
+
+<p>WebSocket 接続を介して受信されるテキストは、 UTF-8 形式です。</p>
+
+<h2 id="Closing_the_connection" name="Closing_the_connection">接続を閉じる</h2>
+
+<p>WebSocket 接続の使用を終了したら、 WebSocket のメソッド {{domxref("WebSocket.close", "close()")}} を呼び出します。</p>
+
+<pre class="brush: js">exampleSocket.close();
+</pre>
+
+<p>接続を閉じようとする前に、ソケットの {{domxref("WebSocket.bufferedAmount", "bufferedAmount")}} 属性を確認して、データがネットワーク上でまだ送信されていないかどうかを判断すると有用かもしれません。この値が 0 ではない場合、まだ待ち状態のデータがあるので、接続を閉じる前に待ったほうが良いかもしれません。</p>
+
+<h2 id="Security_considerations" name="Security_considerations">セキュリティの考慮事項</h2>
+
+<p>混合コンテンツ環境では WebSocket を使用しないでください。つまり、 HTTPS を使用もしくはそうでない方法でもロードされたページから、セキュアでない WebSocket 接続を開くべきではありません。最近のブラウザーは安全な WebSocket 接続のみを許可し、また安全ではないコンテキストでの使用には対応しなくなってきています。</p>
diff --git a/files/ja/web/api/websockets_api/writing_websocket_server/index.html b/files/ja/web/api/websockets_api/writing_websocket_server/index.html
new file mode 100644
index 0000000000..4f0df00628
--- /dev/null
+++ b/files/ja/web/api/websockets_api/writing_websocket_server/index.html
@@ -0,0 +1,273 @@
+---
+title: C# で WebSocket サーバーを記述する
+slug: Web/API/WebSockets_API/Writing_WebSocket_server
+tags:
+ - HTML5
+ - NeedsMarkupWork
+ - WebSockets
+ - チュートリアル
+translation_of: Web/API/WebSockets_API/Writing_WebSocket_server
+---
+<h2 id="イントロダクション">イントロダクション</h2>
+
+<p>WebSocket API を使用したい場合は、サーバーを持っている場合に便利です。この記事では、C# で記述する方法を説明します。どんなサーバーサイドの言語でも行うことができますが、わかりやすく理解しやすいように、Microsoft の言語を選択しました。</p>
+
+<p>このサーバーは <a href="http://tools.ietf.org/html/rfc6455">RFC 6455</a> に準拠しているため、Chrome バージョン16、Firefox 11、IE 10 以上の接続のみを処理します。</p>
+
+<h2 id="ファーストステップ">ファーストステップ</h2>
+
+<p>WebSocket は <a href="http://en.wikipedia.org/wiki/Transmission_Control_Protocol">TCP (伝送制御プロトコル)</a> 接続を介して通信します。幸いにも、C# には <a href="https://docs.microsoft.com/ja-jp/dotnet/api/system.net.sockets.tcplistener?view=netframework-4.7.2">TcpListener</a> クラスがあり、その名前が示すようにします。これは System.Net.Sockets 名前空間にあります。</p>
+
+<div class="note">
+<p><span style="line-height: 1.572;">少なく書くためには名前空間を using キーワードに含めることをお勧めします。毎回完全な名前空間を入力することなく、名前空間のクラスを使用できます。</span></p>
+</div>
+
+<h3 id="TcpListener">TcpListener</h3>
+
+<p>コンストラクタ:</p>
+
+<pre class="brush: cpp">TcpListener(System.Net.IPAddress localaddr, int port)</pre>
+
+<p><code>localaddr</code> はリスナーの IP を指定し、<code>port</code> はポートを指定します。</p>
+
+<div class="note">
+<p><span style="line-height: 1.572;"><code>string</code> から<code>IPAddress</code> オブジェクトを作成するには、</span><code>IPAddress</code><span style="line-height: 1.572;"> の静的 </span><code>Parse</code><span style="line-height: 1.572;"> メソッドを使用します。</span></p>
+</div>
+
+<p><span style="line-height: 1.572;">メソッド</span><span style="line-height: 1.572;">:</span></p>
+
+<ul>
+ <li><code><span style="line-height: 1.572;">Start()</span></code></li>
+ <li><span style="line-height: 1.572;"><code>System.Net.Sockets.<a href="https://docs.microsoft.com/ja-jp/dotnet/api/system.net.sockets.tcpclient?redirectedfrom=MSDN&amp;view=netframework-4.7.2" title="http://msdn.microsoft.com/en-us/library/system.net.sockets.tcpclient.aspx">TcpClient</a> AcceptTcpClient()</code><br>
+ Tcp 接続を待ち、それを受け取り、TcpClient オブジェクトとして返します。</span></li>
+</ul>
+
+<p><span style="line-height: 1.572;">ベアボーンサーバーの実装は次のとおりです。</span></p>
+
+<pre class="brush: cpp">​using System.Net.Sockets;
+using System.Net;
+using System;
+
+class Server {
+ public static void Main() {
+ TcpListener server = new TcpListener(IPAddress.Parse("127.0.0.1"), 80);
+
+ server.Start();
+ Console.WriteLine("Server has started on 127.0.0.1:80.{0}Waiting for a connection...", Environment.NewLine);
+
+ TcpClient client = server.AcceptTcpClient();
+
+ Console.WriteLine("A client connected.");
+ }
+}
+</pre>
+
+<h3 id="TcpClient"><span style="line-height: 1.572;">TcpClient</span></h3>
+
+<p>メソッド:</p>
+
+<ul>
+ <li><code>System.Net.Sockets.<a href="http://msdn.microsoft.com/ja-jp/library/system.net.sockets.networkstream.aspx" title="http://msdn.microsoft.com/en-us/library/system.net.sockets.networkstream.aspx">NetworkStream</a> GetStream()</code><br>
+ 通信チャネルであるストリームを取得します。チャンネルの両側には読み書き機能があります。</li>
+</ul>
+
+<p>プロパティ:</p>
+
+<ul>
+ <li><code>int Available</code><br>
+ このプロパティは送信されたデータのバイト数を示します。値は <code>NetworkStream.DataAvailable</code> が true になるまでゼロです。</li>
+</ul>
+
+<h3 id="NetworkStream">NetworkStream</h3>
+
+<p>メソッド:</p>
+
+<ul>
+ <li><code>Write(Byte[] buffer, int offset, int size)</code><br>
+ buffer からバイトを書き込み、offset と size はメッセージの長さを決定します。</li>
+ <li><code><span class="brush: cpp" style="line-height: 1.572;">Read(Byte[] buffer, int offset, int size)</span></code><br>
+ buffer を読み込みます。offset と size はメッセージの長さを決定します。</li>
+</ul>
+
+<p>私たちの例を拡張してみましょう。</p>
+
+<pre class="brush: cpp">TcpClient client = server.AcceptTcpClient();
+
+Console.WriteLine("A client connected.");
+
+NetworkStream stream = client.GetStream();
+
+//enter to an infinite cycle to be able to handle every change in stream
+while (true) {
+ while (!stream.DataAvailable);
+
+ Byte[] bytes = new Byte[client.Available];
+
+ stream.Read(bytes, 0, bytes.Length);
+}</pre>
+
+<h2 id="ハンドシェイキング">ハンドシェイキング</h2>
+
+<p>クライアントがサーバーに接続すると、単純な HTTP リクエストから WebSocket への接続をアップグレードするための GET リクエストが送信されます。これはハンドシェイキングと呼ばれます。</p>
+
+<p>このサンプルコードはクライアントから GET を検出できます。これは、メッセージの最初の 3 バイトが利用可能になるまでブロックされることに注意してください。運用環境では、代替ソリューションを検討する必要があります。</p>
+
+<pre class="brush: cpp">using System.Text;
+using System.Text.RegularExpressions;
+
+while(client.Available &lt; 3)
+{
+ // wait for enough bytes to be available
+}
+
+Byte[] bytes = new Byte[client.Available];
+
+stream.Read(bytes, 0, bytes.Length);
+
+//translate bytes of request to string
+String data = Encoding.UTF8.GetString(bytes);
+
+if (Regex.IsMatch(data, "^GET")) {
+
+} else {
+
+}</pre>
+
+<p>リクエストは簡単に作成できますが、理解するのは少し難しいかもしれません。サーバーのハンドシェイクの完全な説明は <a href="https://developer.mozilla.org/ja/docs/Web/API/WebSockets_API/RFC%206455,%20section%204.2.2">RFC 6455、セクション4.2.2</a> にあります。私たちの目的のために、簡単なレスポンスを作成します。</p>
+
+<p>やらなければならないのは:</p>
+
+<ol>
+ <li>先行または後続空白なしで "Sec-WebSocket-Key" リクエストヘッダーの値を取得します</li>
+ <li>それを "258EAFA5-E914-47DA-95CA-C5AB0DC85B11" (RFC 6455 で指定された特別な GUID)</li>
+ <li>新しい値の SHA-1 および Base64 ハッシュを計算します</li>
+ <li>HTTP レスポンスの "Sec-WebSocket-Accept" レスポンスヘッダの値としてハッシュを書き戻します</li>
+</ol>
+
+<pre class="brush: cpp"><em>
+</em>if (new System.Text.RegularExpressions.Regex("^GET").IsMatch(data))
+{
+    const string eol = "\r\n"; // HTTP/1.1 defines the sequence CR LF as the end-of-line marker
+
+    Byte[] response = Encoding.UTF8.GetBytes("HTTP/1.1 101 Switching Protocols" + eol
+        + "Connection: Upgrade" + eol
+        + "Upgrade: websocket" + eol
+        + "Sec-WebSocket-Accept: " + Convert.ToBase64String(
+            System.Security.Cryptography.SHA1.Create().ComputeHash(
+                Encoding.UTF8.GetBytes(
+                    new System.Text.RegularExpressions.Regex("Sec-WebSocket-Key: (.*)").Match(data).Groups[1].Value.Trim() + "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"
+                )
+            )
+        ) + eol
+        + eol);
+
+    stream.Write(response, 0, response.Length);
+}
+</pre>
+
+<h2 id="メッセージのデコード">メッセージのデコード</h2>
+
+<p>ハンドシェイクが成功すると、クライアントはエンコードされたメッセージをサーバーに送信します。</p>
+
+<p>"MDN" を送信すると、次のバイトが得られます。</p>
+
+<table>
+ <tbody>
+ <tr>
+ <td>129</td>
+ <td>131</td>
+ <td>61</td>
+ <td>84</td>
+ <td>35</td>
+ <td>6</td>
+ <td>112</td>
+ <td>16</td>
+ <td>109</td>
+ </tr>
+ </tbody>
+</table>
+
+<p>これらのバイトの意味を見てみましょう。</p>
+
+<p>現在 129 の値を持つ最初のバイトは、次のように分解するビットフィールドです。</p>
+
+<table>
+ <thead>
+ <tr>
+ <th scope="col">FIN (Bit 0)</th>
+ <th scope="col">RSV1 (Bit 1)</th>
+ <th scope="col">RSV2 (Bit 2)</th>
+ <th scope="col">RSV3 (Bit 3)</th>
+ <th scope="col">Opcode (Bit 4:7)</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td>1</td>
+ <td>0</td>
+ <td>0</td>
+ <td>0</td>
+ <td>0x1=0001</td>
+ </tr>
+ </tbody>
+</table>
+
+<ul>
+ <li>FIN ビット: このビットは完全なメッセージがクライアントから送信されたかどうかを示します。メッセージはフレームで送信されるかもしれませんが、今のところ単純なものにします。</li>
+ <li>RSV1, RSV2, RSV3: エクステンションがネゴシエートされない限り、これらのビットは 0 でなくてはなりません。</li>
+ <li><span style="line-height: 1.572;">Opcode: </span>これらのビットは受信したメッセージのタイプを記述します。<span style="line-height: 1.572;">Opcode</span> 0x1 は、これがテキストメッセージであることを意味します。<span style="line-height: 1.572;"> </span><a href="http://tools.ietf.org/html/rfc6455#section-5.2" style="line-height: 1.572;" title="http://tools.ietf.org/html/rfc6455#section-5.2">Opcode の完全なリスト</a></li>
+</ul>
+
+<p>現在 131 の値を持つ 2 番目のバイトは、次のように分解する別のビットフィールドです。</p>
+
+<table>
+ <thead>
+ <tr>
+ <th scope="col">MASK (Bit 0)</th>
+ <th scope="col">ペイロードの長さ (Bit 1:7)</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td>1</td>
+ <td>0x83=0000011</td>
+ </tr>
+ </tbody>
+</table>
+
+<ul>
+ <li>MASK ビット: "ペイロードデータ" がマスクされているかどうかを定義します。1 に設定すると、マスキングキーが Masking-Key にあり、これは "ペイロードデータ" のマスクを解除するために使用されます。クライアントからサーバーへのすべてのメッセージはこのビットが設定されています。</li>
+ <li>ペイロードの長さ: この値が 0〜125 の場合、メッセージの長さになります。126 の場合、次の 2 バイト (16ビットの符号なし整数) が長さになります。127 の場合、次の 8 バイト (64ビットの符号なし整数) が長さになります。</li>
+</ul>
+
+<div class="note">
+<p>最初のビットはクライアントからサーバーへのメッセージでは常に 1 なので、このバイトから 128 を引いて MASK ビットを取り除くことができます。</p>
+</div>
+
+<p>メッセージに MASK ビットが設定されていることに注意してください。これは次の4バイト (61、84、35、および6) がメッセージのデコードに使用されるマスクバイトであることを意味します。これらのバイトはすべてのメッセージとともに変化します。</p>
+
+<p>残りのバイトはエンコードされたメッセージペイロードです。</p>
+
+<h3 id="アルゴリズムのデコード">アルゴリズムのデコード</h3>
+
+<p><em>D<sub>i</sub></em> = <em>E<sub>i</sub></em> XOR <em>M</em><sub>(<em>i</em> mod 4)</sub></p>
+
+<p>D は復号されたメッセージ配列、E は符号化されたメッセージ配列、M はマスクバイト配列、i はデコードするメッセージバイトのインデックスです。</p>
+
+<p>C# の例です:</p>
+
+<pre class="brush: cpp">Byte[] decoded = new Byte[3];
+Byte[] encoded = new Byte[3] {112, 16, 109};
+Byte[] mask = new Byte[4] {61, 84, 35, 6};
+
+for (int i = 0; i &lt; encoded.Length; i++) {
+ decoded[i] = (Byte)(encoded[i] ^ mask[i % 4]);
+}</pre>
+
+<h2 id="関連">関連</h2>
+
+<ul>
+ <li><a href="/ja/docs/WebSockets-840092-dup/Writing_WebSocket_servers">Writing WebSocket servers</a></li>
+</ul>
+
+<div id="cke_pastebin" style="position: absolute; top: 2209.23px; width: 1px; height: 1px; overflow: hidden; left: -1000px;"><em> </em></div>
diff --git a/files/ja/web/api/websockets_api/writing_websocket_servers/index.html b/files/ja/web/api/websockets_api/writing_websocket_servers/index.html
new file mode 100644
index 0000000000..2dbf4fe7da
--- /dev/null
+++ b/files/ja/web/api/websockets_api/writing_websocket_servers/index.html
@@ -0,0 +1,242 @@
+---
+title: WebSocket サーバーの記述
+slug: Web/API/WebSockets_API/Writing_WebSocket_servers
+tags:
+ - HTML5
+ - NeedsContent
+ - NeedsExample
+ - WebSocket
+ - WebSockets
+ - ガイド
+ - チュートリアル
+translation_of: Web/API/WebSockets_API/Writing_WebSocket_servers
+---
+<p><span class="seoSummary">WebSocket サーバは、特定のプロトコルに従うサーバの任意のポートを待機する TCP アプリケーションです。カスタムサーバーを作成する作業は人々を悩ませる傾向があります。ただし、選択したプラットフォームに簡単な WebSocket サーバーを実装するのは簡単です。</span></p>
+
+<p>WebSocket サーバは、C(++) や Python、PHP や<a href="/ja/docs/Web/JavaScript/Server-Side_JavaScript">サーバサイド JavaScript</a> などの <a href="https://en.wikipedia.org/wiki/Berkeley_sockets">Berkeley sockets</a> が利用可能なサーバサイドプログラミング言語で記述できます。これは特定の言語のチュートリアルではありませんが、独自のサーバーの作成を容易にするガイドとして役立ちます。</p>
+
+<p>あなたはまだ HTTP がどのように動くのかを知り、中級プログラミング経験を得ている必要があるでしょう。言語サポートによっては、TCP ソケットに関する知識が必要な場合があります。このガイドの範囲は、WebSocket サーバーを作成するために必要な最小限の知識を提示することです。</p>
+
+<div class="note">
+<p>最新の公式 WebSockets 仕様である <a href="http://datatracker.ietf.org/doc/rfc6455/?include_text=1">RFC 6455</a> を参照してください。セクション 1 と 4-7 はサーバー実装者にとって特に興味深いものです。第 10 章ではセキュリティについて説明しています。サーバーを公開する前にセキュリティを正しく理解する必要があります。</p>
+</div>
+
+<p>ここでは WebSocket サーバについて非常に低いレベルで説明しています。WebSocket サーバは多くの場合、リバースプロキシ (通常の HTTP サーバなど) を使用して WebSocket ハンドシェイクを検出、事前処理し、それらのクライアントを実際の WebSocket サーバに送信します。つまり、(例えば) クッキーと認証ハンドラーを使用してサーバ側のコードを膨らませる必要はありません。</p>
+
+<h2 id="WebSocket_ハンドシェイク"><a name="Handshake">WebSocket ハンドシェイク</a></h2>
+
+<p>まず、サーバーは標準の TCP ソケットを使用して着信ソケット接続を待ち受ける必要があります。プラットフォームによっては、すでに処理されている可能性があります。たとえば、サーバーが example.com、8000番ポートで待ち受けているとし、ソケットサーバーが <code>/chat</code> で GET リクエストにレスポンスしたとします。</p>
+
+<div class="warning">
+<p><strong>警告:</strong> サーバーは選択したポートで待機しますが、80 または 443 以外のポートを選択すると、ファイアウォールやプロキシに問題が発生する可能性があります。443番ポートの接続はより頻繁に成功する傾向がありますが、もちろんその接続には安全な接続 (TLS/SSL) が必要です。また、ほとんどのブラウザ (特に Firefox 8 以降) ではセキュリティで保護されていない WebSocket サーバーへの接続を許可していないことに注意してください。</p>
+</div>
+
+<p>ハンドシェイクは WebSockets の "Web" です。それは HTTP から WS への橋渡しです。ハンドシェイクでは、接続の詳細がネゴシエートされ、いずれの当事者も条件が悪い場合には完了前に取り消すことができます。 サーバーはクライアントがリクエストするすべてをのものを理解するように注意する必要があります。そうしないとセキュリティの問題が発生します。</p>
+
+<div class="note">
+<p><strong>Tip:</strong> request-uri (ここでは<code>/chat</code>) は仕様に定義された意味を持ちません。多くの人がうまくそれを使用して、あるサーバーが複数の WebSocket アプリケーションを処理できるようにします。たとえば、<code>example.com/chat</code> はマルチユーザチャットアプリを呼び出すことができ、同じサーバの <code>/game</code> はマルチプレイヤーゲームを呼び出すことができます。</p>
+</div>
+
+<h3 id="クライアントハンドシェイクリクエスト">クライアントハンドシェイクリクエスト</h3>
+
+<p>サーバーを構築しているにもかかわらず、依然としてクライアントは WebSocket ハンドシェイクプロセスを開始する必要があります。したがってクライアントのリクエストをどのように解釈するかを知っておく必要があります。<strong>クライアント</strong>は次のようなかなり標準的な HTTP リクエスト (HTTP バージョンは 1.1 以上<strong>でなければならず</strong>、メソッドは<code>GET</code> <strong>でなければなりません</strong>) を送信します。</p>
+
+<pre class="line-numbers language-html notranslate"><code class="language-html">GET /chat HTTP/1.1
+Host: example.com:8000
+<strong>Upgrade: websocket
+Connection: Upgrade</strong>
+Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
+Sec-WebSocket-Version: 13</code></pre>
+
+<p>クライアントはここで拡張子 および/または サブプロトコルを求めることができます。詳細は「<a href="/ja/docs/WebSockets-840092-dup/Writing_WebSocket_servers#Miscellaneous_2">その他</a>」を参照してください。また <code>User-Agent</code>、<code>Referer</code>、<code>Cookie</code>、認証ヘッダーなどの一般的なヘッダーも存在する可能性があります。あなたはそれらで何でもしてください。WebSocket には直接関係しません。それらを無視することも安全です。多くの一般的な設定では、リバースプロキシは既にそれらを処理しています。</p>
+
+<div class="note">
+<p><strong>Tip:</strong> すべての<strong>ブラウザ</strong>は <a href="/ja/docs/Web/HTTP/HTTP_access_control#Origin"><code>Origin</code> ヘッダー</a>を送信します。 このヘッダをセキュリティ (同じ起点のチェック、ホワイトリスト/ブラックリストなど) に使用し、あなたが見ているものが気に入らなければ <a href="/ja/docs/Web/HTTP/Status#403">403 Forbidden</a> を送ることができます。ただし、ブラウザ以外のエージェントは、偽の <code>Origin</code> を送信するだけであることに注意してください。ほとんどのアプリケーションは、このヘッダーのない要求を拒否します。</p>
+</div>
+
+<p>ヘッダーが解釈されていないか値が正しくない場合、サーバーは "<a href="https://developer.mozilla.org/en-US/docs/HTTP/Response_codes#400">400 Bad Request</a>" を送信し、すぐにソケットを閉じる必要があります。通常は、HTTP レスポンス本体でハンドシェークが失敗した理由を示すかもしれませんが、メッセージは表示されないかもしれません (ブラウザはそれを表示しません)。 サーバーが WebSocket のバージョンを認識しない場合、サーバーは解釈可能なバージョンを含む <code>Sec-WebSocket-Version</code> ヘッダーを返す必要があります。(このガイドでは最新のv13について説明しています)。 ここで、最も興味深いヘッダーである <code>Sec-WebSocket-Key</code> に移動しましょう。</p>
+
+<div class="note">
+<p><strong>Note:</strong> <a href="/ja/docs/Web/HTTP/Status">通常の HTTP ステータスコード</a>は、ハンドシェイクの前にのみ使用できます。ハンドシェイクが成功したら、別のコードセット (仕様の 7.4 節で定義されている) を使用する必要があります。</p>
+</div>
+
+<h3 id="サーバーハンドシェイクレスポンス">サーバーハンドシェイクレスポンス</h3>
+
+<p>このリクエストを受け取ったら、<strong>server</strong> はこれ (各ヘッダーは <code>\r\n</code> で終わり、最後の <code>\r\n</code> は最後に付く) と似たかなり奇妙な (ただしまだ HTTP の) レスポンスを送るべきです。</p>
+
+<pre class="line-numbers language-html notranslate"><code class="language-html"><strong>HTTP/1.1 101 Switching Protocols</strong>
+Upgrade: websocket
+Connection: Upgrade
+<strong>Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
+</strong></code></pre>
+
+<p>さらに、サーバーはここでの 拡張/サブプロトコル リクエストを決定できます。詳細は<a href="/ja/docs/WebSockets-840092-dup/Writing_WebSocket_servers#Miscellaneous">その他</a>を参照してください。<code>Sec-WebSocket-Accept</code> の部分は面白いです。サーバーは、クライアントが送信した <code>Sec-WebSocket-Accept</code> から派生しなければなりません。<br>
+ これを取得するには、クライアントの <code>Sec-WebSocket-Key</code> と <span style="line-height: 1.5em;">"</span><code style="font-size: 14px;">258EAFA5-E914-47DA-95CA-C5AB0DC85B11</code><span style="line-height: 1.5em;">" </span>を連結して (これは "<a href="https://en.wikipedia.org/wiki/Magic_string">マジック文字列</a>" です)、結果の <a href="https://en.wikipedia.org/wiki/SHA-1">SHA-1 ハッシュ</a>を取り、ハッシュのエンコーディングを <a href="https://en.wikipedia.org/wiki/Base64">base64</a> にして返します。</p>
+
+<div class="note">
+<p><strong>FYI:</strong> このように見た目は複雑すぎるプロセスが存在するため、サーバーが WebSocket をサポートしているかどうかはクライアントには明らかです。これはサーバーが WebSockets 接続を受け入れ、HTTP リクエストとしてデータを解釈する場合にセキュリティ上の問題が発生する可能性があるため重要です。</p>
+</div>
+
+<p>したがって、Key が "<code>dGhlIHNhbXBsZSBub25jZQ==</code>" だった場合、Accept は "<code>s3pPLMBiTxaQ9kYGzzhZRbK+xOo=</code>" になります。サーバーがこれらのヘッダーを送信すると、ハンドシェイクは完了し、データのスワップを開始できます。</p>
+
+<div class="note">
+<p>サーバーは、Set-Cookie のような他のヘッダーを送信したり、レスポンスハンドシェイクを送信する前に他のステータスコードで認証またはリダイレクトを要求したりすることができます。</p>
+</div>
+
+<h3 id="クライアントを追跡する">クライアントを追跡する</h3>
+
+<p>これは WebSocket プロトコルには直接関係しませんが、ここで言及する価値はあります。サーバーはクライアントのソケットを追跡して、ハンドシェイクをすでに完了しているクライアントとハンドシェイクを再開しないようにする必要があります。同じクライアント IP アドレスが複数回接続しようとする可能性があります (<a href="https://en.wikipedia.org/wiki/Denial_of_service">サービス拒否攻撃</a>から自分自身を守るためにサーバーが接続を多すぎると拒否することがあります)。</p>
+
+<h2 id="データフレームの交換">データフレームの交換</h2>
+
+<p>クライアントまたはサーバーのいずれかがいつでもメッセージを送信することができます。これが WebSocket の魔法です。しかし、これらのいわゆる「フレーム」のデータから情報を抽出することはあまり魔法のような経験ではありません。すべてのフレームは同じ特定のフォーマットに従いますが、クライアントからサーバーに向かうデータは <a href="https://en.wikipedia.org/wiki/XOR_cipher">XOR 暗号化</a> (32ビットキー) を使用してマスクされます。本明細書の第5節でこれについて詳細に説明する。</p>
+
+<h3 id="フォーマット">フォーマット</h3>
+
+<p>各データフレーム (クライアントからサーバーへ、またはその逆) は、次の同じ形式に従います。</p>
+
+<pre class="line-numbers language-html notranslate"><code class="language-html">Frame format:
+​​
+ 0 1 2 3
+ 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ +-+-+-+-+-------+-+-------------+-------------------------------+
+ |F|R|R|R| opcode|M| Payload len | Extended payload length |
+ |I|S|S|S| (4) |A| (7) | (16/64) |
+ |N|V|V|V| |S| | (if payload len==126/127) |
+ | |1|2|3| |K| | |
+ +-+-+-+-+-------+-+-------------+ - - - - - - - - - - - - - - - +
+ | Extended payload length continued, if payload len == 127 |
+ + - - - - - - - - - - - - - - - +-------------------------------+
+ | |Masking-key, if MASK set to 1 |
+ +-------------------------------+-------------------------------+
+ | Masking-key (continued) | Payload Data |
+ +-------------------------------- - - - - - - - - - - - - - - - +
+ : Payload Data continued ... :
+ + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
+ | Payload Data continued ... |
+ +---------------------------------------------------------------+</code></pre>
+
+<p>MASK ビットはメッセージがエンコードされているかどうかを示します。クライアントからのメッセージはマスクされている必要がありますので、サーバはこのビットが 1 であることを確認する必要があります (実際、<a href="http://tools.ietf.org/html/rfc6455#section-5.1">セクション5.1</a>ではクライアントがマスクされていないメッセージを送信する場合、サーバはクライアントから切断する必要があります)。フレームをクライアントに戻すときは、マスクしたりマスクビットを設定しないでください。後でマスキングについて説明します。注意:セキュアソケットを使用している場合でも、メッセージをマスクする必要があります。RSV1-3 は無視することができますが、それは拡張のためのものです。</p>
+
+<p>opcode フィールドは、ペイロードデータをどのように解釈するかを定義します。継続の場合 <span style="font-family: courier new,andale mono,monospace; line-height: 1.5;">0x0 </span>、テキスト (UTF-8 で常にエンコードされる) の場合は <code style="font-style: normal; line-height: 1.5;">0x1</code>、バイナリの場合は <code style="font-style: normal; line-height: 1.5;">0x2</code>、およびその他のいわゆる「制御コード」については後で説明します。この WebSocket バージョンでは、<span style="line-height: 1.5;"><code>0x3</code> </span>〜  <span style="line-height: 1.5;"><code>0x7</code></span> および <span style="line-height: 1.5;"><code>0xB</code> </span>〜<span style="line-height: 1.5;"><code>0xF</code></span> は意味を持ちません。</p>
+
+<p>FIN ビットは、これがシリーズ内の最後のメッセージであるかどうかを示します。0 の場合、サーバーはメッセージのより多くの部分をリスニングし続けます。それ以外の場合、サーバーは配信されたメッセージを考慮する必要があります。これについては後で詳しく説明します。</p>
+
+<h3 id="ペイロード長のデコード">ペイロード長のデコード</h3>
+
+<p>ペイロードデータを読み取るには、いつ読み終えるべきかを知っておく必要があります。そのためペイロードの長さを知ることが重要です。残念ながら、これはやや複雑です。それを読むには、次の手順を実行します。</p>
+
+<ol>
+ <li>ビット9〜15 (インクルーシブ) を読み取り、それを符号なし整数として解釈します。それが 125 以下であれば、それが長さです。あなたはそれを読み終えました。126 の場合は手順2に、127 の場合は手順3に進みます。</li>
+ <li>次の16ビットを読み取り、それらを符号なし整数として解釈します。 それであなたは読み終えました。</li>
+ <li>次の 64 ビットを読んで、それらを符号なし整数として解釈する(最上位ビットは 0 でなければならない)。それであなたは読み終えました。</li>
+</ol>
+
+<h3 id="データの読み込みとマスク解除">データの読み込みとマスク解除</h3>
+
+<p>MASK ビットがセットされていれば (クライアントからサーバへのメッセージではそうあるべきです)、次の4オクテット (32ビット) を読み込みます。これがマスキングキーです。ペイロード長とマスキングキーがデコードされたら、ソケットからそのバイト数を読み取ることができます。データを <strong>ENCODED</strong>、キーを <strong>MASK</strong> としましょう。<strong>DECODED</strong> を取得するには、<strong>ENCODED</strong> のオクテット (テキストデータの文字のバイト) をループし、オクテットを MASK の (iモジュロ4) オクテットを使用して XOR します。擬似コードの場合(JavaScript が有効な場合)</p>
+
+<pre class="line-numbers language-html notranslate"><code class="language-html">var DECODED = "";
+for (var i = 0; i &lt; ENCODED.length; i++) {
+ DECODED[i] = ENCODED[i] ^ MASK[i % 4];
+}</code></pre>
+
+<p><span style="line-height: 1.5;">これで、アプリケーションに応じて <strong>DECODED</strong> が何を意味するのかを理解することができます。</span></p>
+
+<h3 id="メッセージフラグメンテーション">メッセージフラグメンテーション</h3>
+
+<p>FIN フィールドとオペコードフィールドは連携して、別々のフレームに分割されたメッセージを送信します。これはメッセージフラグメンテーションと呼ばれます。フラグメンテーションは、オペコード <code>0x0</code> 〜 <code>0x2</code> でのみ使用できます。</p>
+
+<p><span style="line-height: 1.5;">オペコードはフレームの意味を示しています。<code>0x1</code> の場合、ペイロードはテキストです。<code>0x2</code> の場合、ペイロードはバイナリデータです。ただし、</span><code style="font-style: normal; line-height: 1.5;">0x0</code><span style="line-height: 1.5;"> の場合、フレームは継続フレームです。つまりサーバーはフレームのペイロードをそのクライアントから受信した最後のフレームに連結する必要があります。ここでは、サーバーがテキストメッセージを送信するクライアントに反応する概略を示します。第1のメッセージは単一のフレームで送信され、第2のメッセージは3つのフレームにわたって送信されます。FIN とオペコードの詳細は、クライアントに対してのみ表示されます。</span></p>
+
+<pre class="line-numbers language-html notranslate" style="font-size: 14px;"><code class="language-html">Client: FIN=1, opcode=0x1, msg="hello"
+Server: (process complete message immediately) Hi.
+Client: FIN=0, opcode=0x1, msg="and a"
+Server: (listening, new message containing text started)
+Client: FIN=0, opcode=0x0, msg="happy new"
+Server: (listening, payload concatenated to previous message)
+Client: FIN=1, opcode=0x0, msg="year!"
+Server: (process complete message) Happy new year to you too!</code></pre>
+
+<p>最初のフレームにメッセージ全体が含まれていることに注意してください(<code>FIN=1</code> および <code>opcode!=0x0</code>)、それによりサーバは適切に処理またはレスポンスできます。クライアントが送信した2番目のフレームにはテキストペイロード (<code>opcode=0x1</code>) がありますが、メッセージ全体がまだ到着していません (<code>FIN=0</code>)。そのメッセージの残りの部分はすべて継続フレーム(<code>opcode=0x0</code>) と共に送信され、メッセージの最終フレームは <code>FIN=1</code> でマークされます。<a href="http://tools.ietf.org/html/rfc6455#section-5.4">仕様の 5.4 節</a>では、メッセージフラグメンテーションについて説明があります。</p>
+
+<h2 id="Ping_と_Pong_WebSockets_のハートビート">Ping と Pong: WebSockets のハートビート</h2>
+
+<p>ハンドシェイク後の任意の時点で、クライアントまたはサーバのどちらかが、相手にpingを送信することを選択できます。 pingが受信されると、受信者はできるだけ早くpongを返さなければなりません。 これを使用して、たとえばクライアントがまだ接続されていることを確認できます。</p>
+
+<p>Ping や Pong は単なる通常のフレームですが、<strong>コントロールフレーム</strong>です。ping のオペコードは <code>0x9</code>、pong のオペコードは <code>0xA</code> です。ping を取得したら、ping と同じペイロードデータを持つ pong を送ります (ping と pong の場合、最大ペイロード長は125です)。ping を送信することなく pong を取得することもできます。その場合はこれを無視してください。</p>
+
+<div class="note">
+<p>あなたが pong を送信する機会を得る前に複数の ping を取得した場合でも、1つの pong しか送信しません。</p>
+</div>
+
+<h2 id="接続を閉じる">接続を閉じる</h2>
+
+<p>クライアントまたはサーバの接続を閉じるには指定した制御シーケンスを含むデータの制御フレームを送信して、終了ハンドシェイクを開始します (<a href="http://tools.ietf.org/html/rfc6455#section-5.5.1">5.5.1 項</a>を参照)。このようなフレームを受信すると、もう1つの peer はレスポンスとしてクローズフレームを送信します。最初の peer は接続を閉じます。接続の終了後に受信されたそれ以上のデータは、その後破棄されます。</p>
+
+<h2 id="その他"><a name="Miscellaneous">その他</a></h2>
+
+<div class="note">
+<p>WebSocket コード、エクステンション、サブプロトコルなどは、<a href="http://www.iana.org/assignments/websocket/websocket.xml">IANA WebSocket プロトコルレジストリ</a>に登録されています。</p>
+</div>
+
+<p>WebSocket のエクステンションとサブプロトコルは、ハンドシェイク中にヘッダーを介してネゴシエートされます。エクステンションとサブプロトコルは異なるものというにはあまりにも似ていることがありますが、明確な区別があります。エクステンションは WebSocket <strong>フレーム</strong>を制御し、ペイロードを<strong>変更</strong>しますが、サブプロトコルは WebSocket <strong>ペイロード</strong>を構造化しますが、<strong>何も変更しません</strong>。エクステンションは任意のもので一般化されています (圧縮など)。サブプロトコルは必須のもので、ローカライズされています (チャットや MMORPG ゲームなど)。</p>
+
+<h3 id="エクステンション">エクステンション</h3>
+
+<div class="note">
+<p><strong>このセクションは拡張が必要です。あなたがそうする準備ができている場合は編集してください。</strong></p>
+</div>
+
+<p>エクステンションはファイルを誰かに電子メールで送る前に圧縮していると考えてください。あなたが何をしても、同じデータをさまざまな形で送信しています。受信者は最終的にローカルコピーと同じデータを得ることができますが、別の方法で送信されます。それがエクステンションの機能です。WebSockets はプロトコルとデータを送信する簡単な方法を定義しますが、圧縮などのエクステンションでは同じデータを短い形式で送信することができます。</p>
+
+<div class="note">
+<p>エクステンションについては、仕様の 5.8, 9, 11.3.2, 11.4 節で説明しています。</p>
+</div>
+
+<p><em>TODO</em></p>
+
+<h3 id="サブプロトコル">サブプロトコル</h3>
+
+<p>サブプロトコルをカスタム <a href="https://en.wikipedia.org/wiki/XML_schema">XML スキーマ</a>または <a href="https://en.wikipedia.org/wiki/Document_Type_Definition">doctype 宣言</a>と考えてください。あなたはまだ XML とその構文を使用していますが、あなたが合意した構造によってさらに制限されます。WebSocket のサブプロトコルはまさにそのようなものです。それらは空想的な何かを導入しておらず、構造を確立するだけです。doctype やスキーマと同様に、両者はサブプロトコルに同意しなければなりません。doctype やスキーマとは異なり、サブプロトコルはサーバー上に実装されており、クライアントから外部参照することはできません。</p>
+
+<div class="note">
+<p>サブプロトコルは、仕様のセクション 1.9, 4.2, 11.3.4、および 11.5 で説明されています。</p>
+</div>
+
+<p>クライアントは特定のサブプロトコルを要求する必要があります。 これを行うには、<strong>元のハンドシェイクの一部として</strong>次のようなものを送ります:</p>
+
+<pre class="line-numbers language-html notranslate"><code class="language-html">GET /chat HTTP/1.1
+...
+Sec-WebSocket-Protocol: soap, wamp</code></pre>
+
+<p>または同様に:</p>
+
+<pre class="line-numbers language-html notranslate"><code class="language-html">...
+Sec-WebSocket-Protocol: soap
+Sec-WebSocket-Protocol: wamp</code></pre>
+
+<p>これでサーバーはクライアントが提案してサポートしているプロトコルの1つを選択する必要があります。複数ある場合は、クライアントが送信した最初のものを送信します。私たちのサーバーが <code>soap</code> と <code>wamp</code> の両方を使用できると想像してください。 次に、レスポンスハンドシェイクで次のメッセージが送信されます。</p>
+
+<pre class="line-numbers language-html notranslate"><code class="language-html">Sec-WebSocket-Protocol: soap</code></pre>
+
+<div class="warning">
+<p>サーバーは複数の <code>Sec-Websocket-Protocol</code> ヘッダーを送信できません。<br>
+ サーバーがサブプロトコルを使用したくない場合、<strong style="line-height: 1.5;"><code>Sec-WebSocket-Protocol</code> </strong><strong>ヘッダーを送信すべきではありません</strong>。 空白のヘッダーを送信するのが間違っています。<br>
+ クライアントは、必要なサブプロトコルを取得できない場合に接続を閉じることがあります。</p>
+</div>
+
+<p>サーバーが特定のサブプロトコルに従うようにしたいのであれば、必然的にサーバー上に特別なコードが必要になります。<code>json</code> サブプロトコルを使用しているとしましょう。このサブプロトコルではすべてのデータが <a href="https://en.wikipedia.org/wiki/JSON">JSON</a> として渡されます。クライアントがこのプロトコルを要求し、サーバーがそれを使用したい場合、サーバーは JSON パーサーを持つ必要があります。実際に言えば、これはライブラリの一部になりますが、サーバーはデータを渡す必要があります。</p>
+
+<div class="note">
+<p><strong>Tip:</strong> 名前の競合を避けるため、サブプロトコル名をドメイン文字列の一部にすることをお勧めします。Example Inc. 専用の独自の形式を使用するカスタムチャットアプリを構築する場合は、次のように使用します: <code>Sec-WebSocket-Protocol: chat.example.com</code>。これは必須ではないことに注意してください。これは単なるオプションです。任意の文字列を使用できます。</p>
+</div>
+
+<h2 id="関連">関連</h2>
+
+<ul>
+ <li><a href="https://github.com/alexhultman/libwshandshake">WebSocket handshake library in C++</a></li>
+ <li><a href="https://developer.mozilla.org/en-US/docs/WebSockets/Writing_WebSocket_server" title="/en-US/docs/WebSockets/Writing_WebSocket_server">Tutorial: Websocket server in C#</a></li>
+ <li><a href="https://developer.mozilla.org/en-US/docs/WebSockets/Writing_WebSocket_client_applications">Writing WebSocket client applications</a></li>
+ <li><a href="https://developer.mozilla.org/en-US/docs/WebSockets/WebSocket_Server_Vb.NET">Tutorial: Websocket server in VB.NET</a></li>
+</ul>