web-dev-qa-db-ja.com

Webソケットはajax / CORSを廃止しますか?

すべてのWebブラウザでWebソケットを使用すると、Ajaxは廃止されますか?

原因は、Webソケットを使用してデータをフェッチし、リアルタイムでデータを更新できる場合、なぜAjaxが必要なのですか?アプリケーションの起動時にajaxを使用してデータを一度だけ取得したとしても、しばらくしてからこのデータが変更されたかどうかを確認したい場合があります。

また、クロスドメインでWebソケットが可能になるのか、それとも同じオリジンのみで可能になるのか?

49
ajsie

WebSocketsはAJAXを完全に廃止しません。WebSocketsはクロスドメインを実行できます。

AJAX

AJAXメカニズムは、プレーンWebサーバーで使用できます。最も基本的なレベルでは、AJAXはWebページがHTTPリクエストを行うための単なる方法です。WebSocketsははるかに低いレベルのプロトコルであり、WebSocketsサーバー(Webサーバーに組み込まれ、スタンドアロン、またはウェブサーバーからスタンドアロンサーバーにプロキシされます)。

WebSocketでは、フレーミングとペイロードはアプリケーションによって決定されます。クライアントとサーバー間でHTML/XML/JSONをやり取りできますが、強制されることはありません。 AJAXはHTTPです。 WebSocketsにはHTTPフレンドリーハンドシェイクがありますが、WebSocketsはHTTPではありません。 WebSocketsは、HTTPよりも(意図的に)rawソケットに近い双方向プロトコルです。 WebSocketsペイロードデータは、標準の現在のバージョンではUTF-8エンコードされていますが、これは将来のバージョンで変更/拡張される可能性があります。

そのため、すべてのクライアントがネイティブにWebSocketをサポートしている世界でも、おそらくAJAXタイプのリクエストのための場所が常にあるでしょう。WebSocketsはAJAX WebSocketsは双方向であり、オーバーヘッドがはるかに低いため)可能またはわずかに可能ですが、WebSocketsはすべてを置き換えませんAJAXが使用されます。

クロスドメイン

はい、WebSocketsはクロスドメインをサポートしています。接続をセットアップするための最初のハンドシェイクは、Originポリシー情報を伝達します。ウィキペディアのページには、典型的なハンドシェイクの例が示されています。 http://en.wikipedia.org/wiki/WebSockets

79
kanaka

これを質問に分解してみます。

すべてのWebブラウザでWebソケットを使用すると、Ajaxは廃止されますか?

絶対違う。 WebSocketは、サーバーへの生のソケット接続です。これには、 独自のセキュリティ問題 が伴います。 AJAX呼び出しは単に非同期です。HTTPリクエストは、他のページと同じ検証手順に従うことができます。

原因は、Webソケットを使用してデータをフェッチし、リアルタイムでデータを更新できる場合、なぜAjaxが必要なのですか?

AJAXを使用すると、より管理しやすいタスクになります。非同期要求を許可するためにソケット接続をセキュリティで保護するオーバーヘッドが必要なわけではありません。これは十分に処理できます。

アプリケーションの起動時にajaxを使用してデータを1回取得するだけでも、しばらくしてからこのデータが変更されたかどうかを確認したい場合があります。

確かに、そのデータが変化している場合。データを変更したり、常に更新したりすることはできません。繰り返しますが、これはコードのオーバーヘッドであり、これを考慮する必要があります。

また、クロスドメインでWebソケットが可能になるのか、それとも同じオリジンのみで可能になるのか?

クロスドメインWebSocketを使用できますが、WSサーバーをコーディングしてそれらを受け入れる必要があります。ドメイン(ホスト)ヘッダーへのアクセス権があり、このヘッダーを使用して要求を許可/拒否できます。ただし、これはncのような単純なものになりすますことができます。接続を本当に保護するには、他の方法で接続を認証する必要があります。

15
Josh K

Websocketには、スケーラビリティに関して、ajaxが回避する大きな欠点がいくつかあります。 ajaxはリクエスト/レスポンスを送信し、誰かがWebページにとどまると接続を閉じる(またはその直後)ため、アイドリング時にサーバーリソースを使用しません。 Websocketは、データをブラウザにストリームバックすることを目的としており、そのためにサーバーリソースを結び付けます。サーバーには、同時に開いておくことができる同時接続の数に制限があります。言うまでもなく、サーバー側の技術によっては、ソケットを処理するスレッドを拘束する場合があります。そのため、WebSocketには、接続ごとの両側でより多くのリソースを消費する要件があります。クライアントにサービスを提供しているすべてのスレッドを簡単に使い果たし、多くのユーザーがページに座っているだけでは、新しいクライアントが入ることはできません。ここで、nodejs、vertx、nettyが実際に役立ちますが、それらにも上限があります。

また、基礎となるソケットの状態の問題があり、ステートフルな会話を実行するコードを両側で記述します。これはステートレスなのでajaxスタイルで行う必要のあることではありません。 Websocketでは、ajaxで解決される低レベルのプロトコルを作成する必要があります。現在、心臓の鼓動、アイドル接続のクローズ、エラー時の再接続などが非常に重要です。これらはステートレスであるため、AJAXを使用する際に解決する必要はありませんでした。状態はアプリの安定性にとって非常に重要であり、さらに重要なのはサーバーの正常性です。事前HTTPは、ステートフルTCPプロトコル(FTP、telnet、SSH)を大量に作成し、その後HTTPが発生しました。 Websocketは、ステートフルプロトコルの長所と短所を取り戻します。

リアルタイムデータのストリーミングが必要な場合、ストリーミングデータを取得するためにサーバーをポーリングすることはより悪いため、この余分なオーバーヘッドが保証されますが、ユーザーインタラクション->リクエスト->レスポンス-> UIの更新のみであれば、ajaxがより簡単になり、使用されます応答が送信されると会話が終了し、追加のサーバーリソースが使用されないため、リソースが少なくなります。だから私はそれはトレードオフだと思うし、アーキテクトはどのツールが彼らの問題に合うかを決めなければならない。 AJAXには場所があり、websocketsには場所があります。

更新

サーバーのアーキテクチャは、スレッドについて話しているときに重要なものです。各ソケット接続がリクエストに応答する独自のスレッドを取得する従来のマルチスレッドサーバー(またはプロセス)を使用している場合、websocketは重要です。したがって、接続ごとにソケットがあり、これらが多すぎると最終的にOSがフォールオーバーし、スレッドについても同じことが言えます(プロセスについても同様です)。スレッドは(リソースの点で)ソケットよりも重いため、同時に実行するスレッドの数を節約しようとします。つまり、すべてのソケットで共有される固定数のスレッドであるスレッドプールを作成します。ただし、ソケットが開かれると、スレッドは会話全体に使用されます。これらの会話の長さは、入ってくる新しいソケットのためにこれらのスレッドを再利用できる速さを左右します。会話の長さは、どれだけ拡張できるかを左右します。ただし、ストリーミングしている場合、このモデルはスケーリングには適していません。スレッド/ソケットの設計を壊す必要があります。

HTTPの要求/応答モデルにより、新しいソケットのスレッドを非常に効率的に切り替えることができます。リクエスト/レスポンスを使用する場合は、すでに構築されているHTTPを使用し、websocketでそのようなものを再実装するよりもはるかに簡単です。

WebsocketはHTTPとしてリクエスト/レスポンスである必要はなく、サーバーのスレッドプールに固定数のスレッドがあり、同じ数のwebsocketがアクティブな会話ですべてのスレッドを結び付けている場合、データをストリーミングできます。入ってくる新しいクライアントにはサービスを提供しません!最大容量に達しました。 Websocketとスレッドでは、プロトコル設計も重要です。プロトコルにより、会話モデルごとのソケットごとにスレッドを緩めることができるため、そこに座っているだけの人はサーバーでスレッドを使用しません。

非同期シングルスレッドサーバーの出番です。InJava非ブロッキングIOに対してこのNIOを呼び出すことがよくあります。つまり、データの送受信がスレッドをブロックしないソケット用の異なるAPIです。呼び出しを実行します。

そのため、socket.read()またはsocket.write()を呼び出すときにソケットをブロックするのが伝統的であり、プログラムに制御を返す前にデータが受信または送信されるまで待機します。つまり、あなたのプログラムは、他のことができるようになるまで、ソケットデータが出入りするのを待って立ち往生しています。そのため、スレッドを使用して、同時に(同時に)作業を行うことができます。クライアントYからのデータを待っている間に、このデータをクライアントXに送信します。同時実行とは、サーバーについて話すときのゲームの名前です。

NIOサーバーでは、単一のスレッドを使用してすべてのクライアントを処理し、データが到着したときに通知されるコールバックを登録します。例えば

socket.read( function( data ) {
   // data is here! Now you can process it very quickly without waiting!
});

Socket.read()呼び出しは、データを読み込まずにすぐに戻りますが、提供された関数が呼び出されると呼び出されます。この設計により、コードのビルド方法と設計方法が根本的に変わります。新しいクライアントを受信しません。一度に2つのことを実行できない単一のスレッドがあります!その1つのスレッドを動かし続ける必要があります。

NIO、非同期IO、イベントベースのプログラムはこれがすべて知られているように、はるかに複雑なシステム設計であり、開始する場合はこれを試して記述することはお勧めしません。非常に上級のプログラマーでさえ、堅牢なシステムを構築することは非常に難しいと感じています。非同期であるため、ブロックするAPIを呼び出すことはできません。 DBからのデータの読み取りや他のサーバーへのメッセージの送信と同様に、非同期で実行する必要があります。ファイルシステムからの読み取り/書き込みでも、シングルスレッドの速度が低下し、スケーラビリティが低下する可能性があります。一度非同期にすると、単一のスレッドを動かし続けたい場合は常にすべて非同期になります。最終的に、DBのような非同期ではないAPIに出くわし、あるレベルでより多くのスレッドを採用する必要があるため、そこが困難になります。そのため、非同期の世界でもハイブリッドアプローチが一般的です。

良いニュースは、この低レベルのAPIを使用して既に使用可能な他のソリューションが構築されていることです。 NodeJS、Vertx、Netty、Apache Mina、Play Framework、Twisted Python、Stackless Pythonなど。C++用のあいまいなライブラリがあるかもしれませんが、正直言って気にしません。サーバーテクノロジーは、CPUの限界を超えるIO限界があるため、非常に高速な言語を必要としません。速度はC++よりも非常に近い(そして時には優れている)嫌いなら、NodeまたはPython。

10
chubbsondubs