Edited at

今さら聞けないWebSocket~WebSocketとは~


WebSocketとは

Webにおいて双方向通信を低コストで行うための仕組み。プロトコルの一種。


WebSocketの必要性


Web通信といえば

HTTP。

主にHTMLで書かれた文書を転送するためのプロトコル。

HTTPの規格が制定された当時のWebは、遠隔地にいる人同士が知識を共有するためにあった。


Webの用途は変わってきた

SNS等の登場によって、リアルタイムなやりとりが求められるようになった。

だれかのアクションがリアルタイムで他のユーザーに伝わり、ほかのユーザーもリアクションすることができる。

このリアルタイムなやり取りを実現するには、サーバ上の情報の更新が行われたらクライアントの画面等を更新する必要などがある。

これをHTTPで実現しようとすると難しい。


HTTPのボトルネック


  • 1つのコネクションで1つのリクエストしか送ることができない

  • リクエストはクライアントからしか送ることができない


    • サーバーから通信を始めることができない



  • ヘッダーが冗長


    • 情報量が多くなってしまう



などなど


HTTPを使って頑張ってきた

それでもHTTPを使ってクライアントとサーバ間の双方向通信を行おうとしてきた。

HTTPを使用してクライアントが一定間隔でサーバに問い合わせをし続けたり(ポーリング)、Cometという手法を用いることによって、サーバ側から通信を開始するサーバプッシュ機能を疑似的に実現していた。

しかし、無駄が多かったり、HTTP自体のボトルネックは解決されることがなかった。

※Comet

問い合わせを受けたサーバは、新着情報がなければレスポンスを返すのをしばらく保留する。新着情報ができればその時点でレスポンスを返し、新着情報ができないようであれば一定時間経過した後にレスポンスを返す。


そこで生まれたWebSocket

これらの問題を解決するために、WebSocketという新しいプロトコルがうまれた。


WebSocketプロトコル

もともとはHTML5の仕様の一部として策定されていたが、現在は単独のプロトコルとして進められている。

WebSocketプロトコルは、サーバとクライアントが一度コネクションを確立すると、その後の通信を専用プロトコルで行う。


  • サーバプッシュ機能


    • 一度コネクションを確立したあとは、サーバとクライアントのどちらからも通信を行うことが可能



  • 通信量削減


    • 一度コネクションを確立するとそのコネクション上で通信を行う(HTTPのように、通信のたびにコネクションを作らない)

    • ヘッダのサイズが最小2byte、最大14byteと小さい



WebSocketプロトコルではまずコネクションの確立(ハンドシェイク)を行うことで、双方向通信の実現がされる


通信の仕組み① -ハンドシェイク-

ハンドシェイクはHTTP通信によって行われる。

リクエスト

HTTPのUpgradeヘッダを使用し、プロトコルの変更を行う。

レスポンス

ステータスコード101「Switching Protocols」が返る。

ハンドシェイクによってコネクションが確立し、これ以降はHTTPではなくWebSocketのプロトコルで通信が行われることになる。


通信の仕組み② -双方向通信の実現-

ハンドシェイクによってコネクションが確立すると、双方向通信をWebSocketプロトコルで行うことができるようになる。

送信データはフレームという単位で扱われる。


よく聞く「socket.io」とは何か

リアルタイムな双方向通信を可能にするNode.jsライブラリとブラウザ用ライブラリのセット。

Javascriptだけでなく、java用ライブラリやC++用ライブラリも出ている。

socket.ioを使うことで、簡単にリアルタイムな双方向通信を実装できる。