WebSocket

WebSocketは、単一のTCPコネクション上に双方向通信のチャンネルを提供する、コンピュータの通信プロトコルの1つである。WebSocketプロトコルは、2011年にRFC 6455としてIETFにより標準化された。Web IDL中のWebSocket APIは、当初W3Cにより標準され、後にWHATWGに引き継がれている。

WebSocketはHTTPとは異なるプロトコルである。ともにOSI参照モデルのレイヤー7に位置し、レイヤー4のTCPに依存している。両者は異なるプロトコルであるが、RFC 6455では、WebSocketは「HTTPプロキシと仲介者をサポートするために、HTTPの443番および80番ポート上で動作するように設計されている」と述べられているように、HTTPプロトコルと互換性がある。互換性を実現するために、WebSocketのハンドシェイクはHTTP/1.1 Upgradeヘッダーを使用し、HTTPプロトコルをWebSocketプロトコルに変更するように実現されている。

標準仕様は以下のように規定されている。

API: [1]。
通信プロトコル: RFC 6455 に加えて[2]
HTTP/2と組み合わせる場合: RFC 8441
HTTP/3と組み合わせる場合: RFC 9220

1. 概要
-----

XMLHttpRequestの欠点を解決する技術として開発されており、既存のComet等に取って代わることを目標としている。

いわゆるAjaxアプリケーションではサーバとクライアント間のデータのやり取りが頻繁に発生するが、従来のXMLHttpRequestはあくまでブラウザ側からサーバにデータの送信要求を出す手段に過ぎず、サーバ側からクライアントにデータをプッシュ配信することが難しい。一方Cometではサーバ側からのプッシュ配信が可能なものの、多くの実装では擬似的に双方向通信を行うため通信が発生するごとにTCPのハンドシェイク手続きを再度行う必要があるほか、HTTPコネクションを長時間占有するためその間同一サーバに接続する他のアプリケーションの動作に影響を及ぼす可能性があるなど、また別の問題が生じる。

これに対しWebSocketでは、サーバとクライアントが一度コネクションを行った後は、必要な通信を全てそのコネクション上で専用のプロトコルを用いて行う。従来の手法に比べると、新たなコネクションを張ることがなくなる・HTTPコネクションとは異なる軽量プロトコルを使うなどの理由により通信ロスが減る、一つのコネクションで全てのデータ送受信が行えるため同一サーバに接続する他のアプリケーションへの影響が少ないなどのメリットがある。

2. プロトコル
--------

WebSocketの接続を確立するために、クライアント側はまずハンドシェイク要求を送る。そして、サーバ側はハンドシェイク応答を返す。以下はHTTP/1.1の場合の例である。

ウェブブラウザが以下の要求をサーバ側に送る：

サーバ側は以下の応答を返す。

ハンドシェイクはHTTPの様であるが、厳密には異なる。サーバ側は最初HTTPの要求として解釈し、そして、WebSocketへと切り替える。

3. URIスキーム
----------

WebSocketプロトコルの仕様書はws: と wss:という2つの新しいURIスキームを定義している。

4. 実装状況
-------

4.1. クライアント
-----------

クライアント側は、Internet Explorer 10、Mozilla Firefox 6 、Google Chrome 4 、Safari 5、Opera 12.10、Android 4.4、BlackBerry 7で実装されている。

ウェブブラウザのプラグインを利用する物

Adobe Flash - jWebsocket FlashBridge
Silverlight - Microsoft WCF WebSockets、CodeProject記事プロトコル上のSec-WebSocket-Version:とドラフト番号の対応関係は以下の通り。hybi-04からプロトコル上に対応するドラフト番号が現れるようになった。



4.2. サーバ
--------

C/C++
[3]
POCO C++ Libraries
[4]
[5]
Go
[6]
Haskell
[7]
Java - Java EE 7 にて Java API for WebSocket  が追加された
Apache Tomcat 7
[8]
GlassFish 3.1, [9]
JBoss 7
Jetty 7
[10]
[11] 3.3
.NET
ASP.NET Core
[12]
Internet Information Services  8, ASP.NET 4.5
[13]
Node.js
[14]
[15]
[16]
Objective-C
[17]
Perl
[18]
[19]
PHP
[20]
Python
[21]
[22]
Ruby
[23]
Scala
[24]
その他
[25]

4.3. 歴史的経緯
----------

プロトコルは2011年5月の完成を目標に進められていたが、その期日を過ぎても仕様の改訂は続けられ、2011年7月11日に最終草案のdraft-ietf-hybi-thewebsocketprotocol-10が勧告されたが、さらにその後も改訂は続き、2011年9月30日に draft-ietf-hybi-thewebsocketprotocol-17がリリースされ、それが2011年12月11日にRFC 6455のproposed standardとなった。

2010年11月26日にdraft-ietf-hybi-thewebsocketprotocol-03やそれ以前のWebSocketのプロトコルにセキュリティホールが発見され、2010年12月に、一時的に、Firefox 4とOpera 11のWebSocketが無効になり、Chromeはプロトコル改訂よりも先に攻撃コードが出た場合は無効にするとしていた。Opera 11はopera:config#Enable%20WebSocketsを開き、設定を有効にすると利用可能。その後、2011年1月11日にdraft-ietf-hybi-thewebsocketprotocol-04が発表され、サーバにアップロード通信する際はプロキシを混乱させないために、通信内容をXORでマスキングさせる方法となった。2011年8月16日に再度WebSocketに対応させた、Firefox 6 がリリースされたが、まだ、仕様の改訂が続くという理由から、Firefox 10までは、MozWebSocketと頭にMozがつく形となった。Firefox for Mobileは7から対応。

ウェブブラウザで動作するJavaScript用のAPIの策定は、当初W3Cで行われていた。その後、HTML5とともにWHATWGに移ることとなった。

WHATWGでは、当初主にHTML Standard内でWebSocketのAPIが規定していた。その後、2021年に別個の仕様に分離することが提起され、WebSockets Standardが創設されることとなった。

5. 関連項目
-------

Push技術
Comet
gRPC

6. 参照
-----

7. 外部リンク
--------

[26]
RFC 6455
[27] - IETF でのインターネットドラフト
[28] - バージョン76にて廃止された Network Working Group の古いバージョン
[29] - WHATWGによるAPIの仕様
W3Cの旧式の規定
[30] W3C Candidate Recommendation 20 September 2012 - API の W3C 勧告候補
[31] W3C Working Group Note, 28 January 2021 - 最終のワーキンググループノート
https://www.websocket.org/}} - WebSocket ウェブサイト
[32]