WebSocket

ウィキペディアから、無料の百科事典
ナビゲーションにジャンプ 検索にジャンプ
WebSocket
Websocket connection.png
WebSocketを使用した接続を説明する図
国際標準RFC  6455
によって開発されたIETF
業界コンピュータサイエンス
コネクタタイプTCP
Webサイト公式サイト

WebSocketはコンピューター通信プロトコルであり、単一のTCP接続を介して全二重通信チャネルを提供します。WebSocketプロトコルはによって標準化されたIETFRFC 6455、2011年に、とのWebSocket APIのWeb IDLはによって標準化されているW3C 

WebSocketはHTTPとは異なります。両方のプロトコルは、に位置している層7OSIモデルとそれらが異なるが層4にTCPに依存して、RFC 6455個のWebSocket「はHTTPプロキシとの仲介をサポートするためにHTTPポート443及び80、並びに上に動作するように設計されていることを状態が、 "したがって、HTTPと互換性があります。互換性を実現するために、WebSocketハンドシェイクHTTPアップグレードヘッダー[1]を使用して、HTTPプロトコルからWebSocketプロトコルに変更します。  

WebSocketプロトコルにより、Webブラウザー(または他のクライアントアプリケーション)とWebサーバー間の対話が可能になり、HTTPポーリングなどの半二重の代替手段よりもオーバーヘッドが少なくなり、サーバーとの間のリアルタイムのデータ転送が容易になります。これは、サーバーが最初にクライアントから要求されることなくコンテンツをクライアントに送信するための標準化された方法を提供し、接続を開いたままメッセージをやり取りできるようにすることで可能になります。このようにして、クライアントとサーバーの間で双方向の継続的な会話を行うことができます。通信は通常TCPポートを介して行われます番号443(またはセキュリティで保護されていない接続の場合は80)。これは、ファイアウォールを使用してWeb以外のインターネット接続をブロックする環境に役立ちます。同様の双方向のブラウザとサーバーの通信は、CometAdobe FlashPlayerなどの一時的なテクノロジーを使用して標準化されていない方法で実現されています[2]

Google ChromeFirefoxMicrosoft EdgeInternet ExplorerSafariOperaなど、ほとんどのブラウザがプロトコルをサポートしています[3]

HTTPとは異なり、WebSocketは全二重通信を提供します。[4] [5] さらに、WebSocketはTCP上でメッセージのストリームを有効にします。 TCPだけでは、メッセージの固有の概念を持たないバイトストリームを処理します。 WebSocket以前は、Cometチャネルを使用してポート80の全二重通信を実現できました。ただし、Cometの実装は重要であり、TCPハンドシェイクとHTTPヘッダーのオーバーヘッドのため、小さなメッセージには非効率的です。 WebSocketプロトコルは、Webのセキュリティの前提を損なうことなくこれらの問題を解決することを目的としています。

WebSocketのプロトコル仕様定義ws(のWebSocket)とwss二つの新しいとして(固定用WebSocket)ユニフォームリソース識別子(URI)スキーム[6]はそれぞれ、暗号化されていないと暗号化された接続のために使用されます。スキーム名とフラグメント(つまり#、サポートされていない)を除いて、残りのURIコンポーネントは、URI汎用構文を使用するように定義されています[7]

開発者は、ブラウザー開発者ツールを使用して、WebSocketハンドシェイクとWebSocketフレームを検査できます。[8]

歴史

WebSocketは、TCPベースのソケットAPIのプレースホルダーとしてHTML5仕様でTCPConnectionとして最初に参照されました[9] 2008年6月、Michael Carterが一連の​​議論を主導し、WebSocketとして知られるプロトコルの最初のバージョンが生まれました。[10]

「WebSocket」という名前は、その後すぐにIanHicksonとMichaelCarterによって#whatwgIRCチャットルームでのコラボレーションによって造られ[11]、その後IanHicksonによってHTML5仕様に含めるために作成されました。2009年12月、Google Chrome 4は、WebSocketがデフォルトで有効になっている、標準の完全サポートを出荷した最初のブラウザでした。[12]その後、WebSocketプロトコルの開発は、2010年2月にW3CおよびWHATWGグループからIETFに移され、IanHicksonの下で2つの改訂のために作成されました。[13]

プロトコルは複数のブラウザでデフォルトで出荷され、有効になった後、RFC 6455は、 2011年12月にイアンたFette下確定されました。  

RFC  7692は、メッセージごとにDEFLATEアルゴリズムを使用してWebSocketに圧縮拡張機能を導入しました。

ブラウザの実装

WebSocketプロトコルの安全なバージョンは、Firefox 6、[14] Safari 6、Google Chrome 14、[15] Opera 12.10、およびInternet Explorer 10に実装されています[16] 詳細なプロトコルテストスイートレポート[17]には、これらの適合性が記載されています。特定のプロトコルの側面へのブラウザ。

プロトコルの古い、安全性の低いバージョンは、Opera11とSafari5およびiOS4.2のモバイルバージョンのSafariに実装されました[18] OS7のBlackBerryBrowserはWebSocketを実装しています。[19]脆弱性のため、Firefox 4および5、[20]、Opera11では無効になっています[21]

実施状況
プロトコル、バージョン ドラフト日 インターネットエクスプローラ Firefox [22](PC) Firefox(Android) Chrome(PC、モバイル) Safari(Mac、iOS) Opera(PC、モバイル) Androidブラウザ
hixie-75 2010年2月4日 4 5.0.0
hixie-76
hybi-00
2010年
5月6日2010年5月23日
4.0(無効) 6 5.0.1 11.00(無効)
hybi-07、v7 2011年4月22日 6 [23] [a]
hybi-10、v8 2011年7月11日 7 [25] [a] 7 14 [26]
RFC  6455、v13 2011年12月 10 [27] 11 11 16 [28] 6 12.10 [29] 4.4

JavaScriptクライアントの例

//パラメータとしてURIをWSと新規のWebSocketオブジェクト作成
CONST ソケット = 新規 のWebSocketを'://game.example.com:WS 12010 /更新' )。

// WebSocketとの接続が開かれたときに発生します、
ソケット開く時 = 関数 () {
  たsetInterval 関数() {
    場合 ソケットbufferedAmount  ==  0 
      ソケットセンドgetUpdateData ()); 
  }、 50 ); 
};

//データがWebSocket、
ソケットを介して受信されたときに発生しますonMessage  = 関数イベント { 
  handleUpdateData イベントデータ)。
};

// WebSocketとの接続が閉じられたときに発生します、
ソケットonclose  =  function event  { 
  onSocketClose event ); 
};

//エラー
socketが原因でWebSocketとの接続が閉じられたときに発生しますonerror  =  function event  { 
  onSocketError event ); 
};

Webサーバーの実装

nginxのは、バージョン1.3.13に実装2013年以来、WebSocketをサポートしている[30]として作用含むリバースプロキシロード・バランサのWebSocketアプリケーション。[31]

Apache HTTP Serverは、2013年7月以降、バージョン2.4.5で実装されたWebSocketをサポートしています[32] [33]

インターネットインフォメーションサービスは、Windows Server2012でリリースされたバージョン8でWebSocketのサポートを追加しました[34]

lighttpdは2017年からWebSocketをサポートしており、バージョン1.4.46で実装されています。[35] lighttpd mod_proxyは、WebSocketアプリケーションのリバースプロキシおよびロードバランサーとして機能できます。lighttpd mod_wstunnelは、WebSocketトンネルを容易にし、クライアントがWebSocketを使用して、JSONなどのより単純なプロトコルをバックエンドアプリケーションにトンネリングできるようにします。

プロトコルハンドシェイク

以下の例に示すように、WebSocket接続を確立するために、クライアントはWebSocketハンドシェイク要求を送信します。サーバーはその要求に対してWebSocketハンドシェイク応答を返します。[36]

クライアントリクエスト(HTTPの場合同様に、各行\r\nはで終わり、最後に余分な空白行が必要です):

GET  / chat  HTTP / 1.1
ホスト server.example.com
アップグレード websocket
接続 アップグレード
Sec-WebSocket-キー x3JJHMbDL1EzLkh9GBhXDw == 
Sec-WebSocket-プロトコル チャット、スーパーチャット
Sec-WebSocket-バージョン 13
オリジン http:// example.com

サーバーの応答:

HTTP / 1.1  101 スイッチングプロトコル
アップグレード websocket
接続 アップグレード
Sec-WebSocket-受け入れ HSmrc0sMlYUkAGmm5OPpG2HaGWk = 
Sec-WebSocket-プロトコル チャット

ハンドシェイクはHTTP要求/応答で始まり、サーバーが同じポートでHTTP接続とWebSocket接続を処理できるようにします。接続が確立されると、通信はHTTPプロトコルに準拠していない双方向のバイナリプロトコルに切り替わります。

Upgradeヘッダーに加えて、クライアントはbase64でエンコードされたランダムバイトSec-WebSocket-Keyを含むヘッダーを送信し、サーバーヘッダー内のキーのハッシュ応答します。これは、キャッシングプロキシが以前のWebSocket会話を再送信するのを防ぐことを目的としており[37]、認証、プライバシー、または整合性を提供しません。ハッシュ関数は、固定文字列UUID)をヘッダー(base64からデコードされない)の値に追加しSHA-1ハッシュ関数を適用し、base64を使用して結果をエンコードします。[38]Sec-WebSocket-Accept 258EAFA5-E914-47DA-95CA-C5AB0DC85B11Sec-WebSocket-Key

RFC6455では、キーは、base64でエンコードされたランダムに選択された16バイトの値[39]、つまりbase64では24バイト(最後の2バイトは==)で構成されるナンスである必要があります。一部の緩和されたHTTPサーバーでは、より短いキーを提示できますが、最近の多くのHTTPサーバーは、「無効なSec-WebSocket-Keyヘッダー」というエラーで要求を拒否します。

接続が確立されると、クライアントとサーバーは全二重モードでWebSocketデータまたはテキストフレームを送受信できます。データは最小限のフレームで構成され、小さなヘッダーの後にペイロードが続きます。[40] WebSocket送信は「メッセージ」として記述され、単一のメッセージをオプションで複数のデータフレームに分割できます。これにより、初期データは使用可能であるがメッセージの完全な長さが不明な場合にメッセージを送信できます(最後に到達し、FINビットでコミットされるまでデータフレームを次々に送信します)。プロトコルの拡張により、これは複数のストリームを同時に多重化するためにも使用できます(たとえば、単一の大きなペイロードに対するソケットの使用を独占することを回避するため)。[41]

セキュリティに関する考慮事項

通常のクロスドメインHTTPリクエストとは異なり、WebSocketリクエストは同一生成元ポリシーによって制限されませんしたがって、WebSocketサーバーは、接続がCookieまたはHTTP認証で認証されている場合に発生する可能性がある、クロスサイトWebSocketハイジャック攻撃(クロスサイトリクエストフォージェリと同様)を回避するために、接続確立中に予想される発信元に対して「Origin」ヘッダーを検証する必要があります。 。機密(プライベート)データがWebSocketを介して転送される場合は、トークンまたは同様の保護メカニズムを使用してWebSocket接続を認証することをお勧めします。[42]脆弱性の実例は、ケーブルホーントの形で2020年に見られました

プロキシトラバーサル

WebSocketプロトコルクライアントの実装は、宛先ホストとポートに接続するときにユーザーエージェントがプロキシを使用するように構成されているかどうかを検出しようとします。構成されている場合は、HTTPCONNECTメソッドを使用して永続トンネルを設定します。

WebSocketプロトコル自体はプロキシサーバーとファイアウォールを認識しませんが、HTTP互換のハンドシェイクを備えているため、HTTPサーバーはデフォルトのHTTPポートとHTTPSポート(それぞれ80と443)をWebSocketゲートウェイまたはサーバーと共有できます。 WebSocketプロトコルは、ws://およびwss://プレフィックスを定義して、それぞれWebSocketおよびWebSocketSecure接続を示します。どちらのスキームも、HTTPアップグレードメカニズム使用してWebSocketプロトコルにアップグレードします。一部のプロキシサーバーは透過的であり、WebSocketで正常に動作します。他の人はWebSocketが正しく機能するのを妨げ、接続が失敗する原因になります。場合によっては、追加のプロキシサーバー構成が必要になることがあり、WebSocketをサポートするために特定のプロキシサーバーをアップグレードする必要がある場合があります。

暗号化されていないWebSocketトラフィックが、WebSocketをサポートしていない明示的または透過的なプロキシサーバーを通過する場合、接続は失敗する可能性があります。[43]

暗号化されたWebSocket接続が使用されている場合、トランスポート層セキュリティの使用WebSocket Secure接続の(TLS)は、ブラウザーが明示的なプロキシー・サーバーを使用するように構成されている場合に、HTTPCONNECTコマンドが発行されることを保証します。これにより、WebSocket SecureクライアントとWebSocketサーバーの間に、HTTPプロキシを介した低レベルのエンドツーエンドTCP通信を提供するトンネルが設定されます。透過プロキシサーバーの場合、ブラウザはプロキシサーバーを認識しないため、HTTPCONNECTは送信されません。ただし、有線トラフィックは暗号化されているため、中間の透過プロキシサーバーは暗号化されたトラフィックの通過を許可するだけである可能性があります。したがって、WebSocket Secureを使用すると、WebSocket接続が成功する可能性がはるかに高くなります。暗号化の使用はリソースコストがかからないわけではありませんが、安全なトンネルを通過するため、多くの場合、最高の成功率を提供します。

2010年半ばのドラフト(バージョンhixie-76)は、ヘッダーの後に8バイトのキーデータを含めることリバースプロキシおよびゲートウェイとの互換性を壊しましたが、そのデータをContent-Length: 8ヘッダーにアドバタイズしませんでした[44]このデータはすべての中間体によって転送されたわけではなく、プロトコルの失敗につながる可能性がありました。最近のドラフト(例:hybi-09 [45])では、キーデータがSec-WebSocket-Keyヘッダーに配置され、この問題が解決されています。

も参照してください

注意事項

  1. ^ a b Geckoベースのブラウザバージョン6〜10は、WebSocketオブジェクトを「MozWebSocket」として実装します[24]。既存のWebSocket対応コードと統合するには追加のコードが必要です。

参考文献

  1. ^ Ian Fette; アレクセイメルニコフ(2011年12月)。「TCPおよびHTTPとの関係」RFC 6455WebSocketプロトコルIETF1.7。土井10.17487 / RFC6455RFC 6455
  2. ^ 「AdobeFlashプラットフォーム-ソケット」help.adobe.com 2021728日取得TCP接続には、「クライアント」と「サーバー」が必要です。FlashPlayerはクライアントソケットを作成できます。
  3. ^ 「WebSockets-ListaWeb API | MDN」development.mozilla.org 2021728日取得
  4. ^ 「用語集:WebSockets」Mozilla DeveloperNetwork。2015年。
  5. ^ 「HTML5WebSocket-Webのスケーラビリティの飛躍的な進歩」www.websocket.org
  6. ^ Graham Klyne、ed。(2011-11-14)。「IANAURI(Uniform Resource Identifer)スキーム」Internet Assigned NumbersAuthority 2011年12月10日取得
  7. ^ Ian Fette; アレクセイメルニコフ(2011年12月)。「WebSocketURI」RFC 6455WebSocketプロトコルIETF3. doi10.17487 / RFC6455RFC 6455
  8. ^ 王、ヴァネッサ; サリム、フランク; モスコビッツ、ピーター(2013年2月)。「付録A:GoogleChrome開発ツールを使用したWebSocketフレーム検査」HTML5WebSocketの決定的なガイド押してください。ISBN 978-1-4302-4740-1取り出さ年4月7 2013
  9. ^ 「HTML5」www.w3.org 2016年4月17取得
  10. ^ 「[whatwg] 2008-06-18のMichaelCarterからのTCPConnectionフィードバック(2008年6月のwhatwg.org)」Lists.w3.org 2016年4月17取得
  11. ^ 「IRCログ:freenode / #whatwg / 20080618」krijnhoetmer.nl 2016年4月18日取得
  12. ^ 「GoogleChromeでWebSocketが利用可能になりました」Chromiumブログ2016年4月17取得
  13. ^ <[email protected]>、イアン・ヒックソン。「WebSocketプロトコル」tools.ietf.org 2016年4月17取得
  14. ^ Dirkjan Ochtman(2011年5月27日)。「Firefox6でWebSocketが有効になっていますMozilla.org 20116月30日取得
  15. ^ 「ChromiumWebプラットフォームのステータス」取り出さ2011-08-03に
  16. ^ 「WebSockets(Windows)」マイクロソフト。2012-09-28 取得した2012年11月7日を
  17. ^ 「WebSocketsプロトコルテストレポート」Tavendo.de。2011-10-27 2011年12月10日取得
  18. ^ Katie Marsal(2010年11月23日)。「AppleはiOS4.2のSafariに加速度計とWebSocketのサポートを追加しました」AppleInsider.com 2011年5月9日取得
  19. ^ 「WebSocketsAPI」BlackBerry2011年6月10日にオリジナルからアーカイブされまし取り出さ年7月8 2011
  20. ^ Chris Heilmann(2010年12月8日)。「Firefox4でWebSocketが無効になっています」Hacks.Mozilla.org 2011年5月9日取得
  21. ^ Aleksander Aas(2010年12月10日)。「WebSocketについて」私のOperaブログアーカイブされたオリジナルの2010年12月15日に2011年5月9日取得
  22. ^ 「WebSockets(Firefoxでのサポート)」development.mozilla.orgMozillaFoundation。2011-09-30 2011年12月10日取得
  23. ^ 「バグ640003-WebSocket-ietf-06にアップグレード」MozillaFoundation。2011-03-08 2011年12月10日取得
  24. ^ 「WebSockets-MDN」development.mozilla.orgMozillaFoundation。2011-09-30 2011年12月10日取得
  25. ^ 「バグ640003-WebSocket-ietf-07(コメント91)にアップグレード」MozillaFoundation。2011年7月22日。
  26. ^ 「クロムバグ64470」code.google.com2010-11-25 2011年12月10日取得
  27. ^ 「WindowsコンシューマープレビューのWebSocket」IEエンジニアリングチームマイクロソフト。2012-03-19 2012年7月23日取得
  28. ^ 「WebKitチェンジセット97247:WebSocket:WebSocketプロトコルをhybi-17に更新」trac.webkit.org 2011年12月10日取得
  29. ^ 「ホットなOpera12.50夏のスナップショット」Opera開発者ニュース。2012-08-03。アーカイブされたオリジナルの2012年8月5日に2012年8月3取得
  30. ^ [1]
  31. ^ 「WebSocketプロキシとしてのNGINXの使用」NGINX2014年5月17日。
  32. ^ 「ApacheHTTPServer2.4の新機能の概要」Apache
  33. ^ 「ChangelogApache2.4」Apacheラウンジ
  34. ^ 「IIS8.0WebSocketプロトコルのサポート」MicrosoftDocs2012年11月28日2020年2月18日取得
  35. ^ [2]
  36. ^ Ian Fette; アレクセイメルニコフ(2011年12月)。「プロトコルの概要」RFC 6455WebSocketプロトコルIETF1.2。土井10.17487 / RFC6455RFC 6455
  37. ^ 「WebSocketプロトコルの主な目標」IETF 検索された25年7月2015計算[...]は、キャッシング仲介者が、WSサーバーとの実際の対話なしに、キャッシュされたWSサーバー応答をWSクライアントに提供することを防ぐことを目的としています。
  38. ^ Ian Fette; アレクセイメルニコフ(2011年12月)。「オープニングハンドシェイク」RFC 6455WebSocketプロトコルIETFNS。8.秒 1.3。土井10.17487 / RFC6455RFC 6455
  39. ^ Ian Fette; アレクセイメルニコフ(2011年12月)。「オープニングハンドシェイク」RFC 6455WebSocketプロトコルIETFNS。21.秒 1.3。土井10.17487 / RFC6455RFC 6455
  40. ^ Ian Fette; アレクセイメルニコフ(2011年12月)。「ベースフレーミングプロトコル」RFC 6455WebSocketプロトコルIETF5.2。土井10.17487 / RFC6455RFC 6455
  41. ^ ジョンA.タンプリン; 吉野武(2013)。WebSocketの多重化拡張機能IETFIDdraft-ietf-hybi-websocket-multixing。
  42. ^ クリスチャンシュナイダー(2013年8月31日)。「クロスサイトWebSocketハイジャック(CSWSH)」Webアプリケーションセキュリティブログ
  43. ^ Peter Lubbers(2010年3月16日)。「HTML5WebSocketがプロキシサーバーとどのように相互作用するか」Infoq.comC4MediaInc 2011年12月10日取得
  44. ^ ウィリータロー(2010-07-06)。「WebSocket-76はHTTPリバースプロキシと互換性がありません」ietf.org(電子メール)。インターネットエンジニアリングタスクフォース2011年12月10日取得
  45. ^ Ian Fette(2011年6月13日)。「Sec-WebSocket-Key」WebSocketプロトコル、ドラフトhybi-0911.4 2011年6月15日取得

外部リンク