
シェア:
Liz AcostaはVonageのDeveloper Advocateです。映画学生からマーケター、エンジニア、デベロッパー・アドボケイトという彼女のキャリア・パスは型破りに見えるかもしれないが、デベロッパー・リレーションズにとってはごく一般的なものだ!ピザ、植物、パグ、Pythonが大好き。
WebSocketとは何か、HTTPとどう違うのか?
所要時間:2 分
リアルタイムのコミュニケーションは、最新のアプリケーションにとって不可欠なものとなっています。ライブチャットから共同編集者、通知システムに至るまで、ページを更新することなくブラウザ内で即座に更新することはごく当たり前になり、この偉業を可能にしている技術を見落としてしまいがちだ。従来のHTTPリクエスト-レスポンスのサイクルでは、クライアントはサーバーとの接続を開始しなければならず、レスポンスを受信すると、その接続は閉じられます。この結果、待ち時間が増加し、リソースの使用効率が悪くなる。ポーリングは1つの回避策ではあるが、インターネット上でのライブ・データ交換の技術的ニーズに対応するにはまだ不十分である。
そこで ウェブソケットが解決策を提供する。WebSocketは、クライアントとサーバ間の永続的な双方向通信を可能にする通信プロトコルです。WebSocketは、Vonageアプリケーションの音声ストリーミング、メッセージング、ライブ・イベント処理などの機能を強化し、開発者がコラボレーション・ツールからライブ・ストリーミング・アプリケーションまで、あらゆるものを構築する方法を変えます。
このブログポストでは、WebSocketとは何か、どのように機能するのか、実際のアプリケーションを紹介し、WebSocketが最新のWebおよびモバイルアプリケーションでライブデータ交換の基盤を形成する方法を示すサンプルコードを見ていきます。
WebSocketの仕組み
WebSocketの最も革新的な特徴の1つは、HTTPとの互換性です。WebSocketは、HTTPからWebSocketにプロトコルを切り替えるためにHTTP Upgradeヘッダーを使用し、クライアントとサーバーの間に持続的な接続を確立し、継続的に通信をやり取りすることができます。
握手
HTTPからWebSocketプロトコルへの移行は、クライアントとサーバー間の最初のハンドシェイクで発生します。クライアントからのハンドシェイクは次のようになります:
GET /chat HTTP/1.1
Host: server.example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
Origin: http://example.com
Sec-WebSocket-Protocol: chat, superchat
Sec-WebSocket-Version: 13ヘッダーに Upgradeヘッダーに websocket.
サーバーは以下のハンドシェイクで応答する:
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
Sec-WebSocket-Protocol: chatハンドシェイクが成功すれば、WebSocketプロトコルの第2パートが開始される。
データ転送
ハンドシェイクの交換に成功した後、コネクションが確立される。 全二重接続が確立される。この接続では、クライアントとサーバーは互いに独立してデータを送信することができる。データは、特定のバイナリー・フレーミング・プロトコルによって定義された「メッセージ」で送信される。
WebSocketのより技術的な側面については、プロトコルのRequest Comments(RFC)を参照してください。 プロトコルのRFC(Request for Comments)を参照してください。.
HTTPとWebSocketの比較
HTTPとは異なり、WebSocketでは接続がオープンなままであるため、クライアントとサーバー間で継続的な双方向通信が可能です。以下は、主要な特徴におけるHTTPとWebSocketの比較です:
アスペクト | HTTP | ウェブソケット |
接続モデル |
|
|
レイテンシー |
|
|
データフロー |
|
|
コネクション・ライフサイクル |
|
|
セキュリティ(暗号化) |
|
|
ポート |
|
|
言い換えれば、HTTPとWebSocketの違いはこう想像できる:
HTTPプロトコルを真似て電話で友人と話そうとすると、あなたは友人に電話をかけなければならず、友人はあなたが話し終わるまで返事を待たなければならず、そして二人とも電話を切ることになる。さらに会話を続けるには、もう一度友人に電話をかけ、友人が応答するまで待たなければならない。さらに、友人は前の電話であなたが何を話したかまったく覚えていない。これではリアルタイムの会話には向かない!
WebSocketを使えば、この比喩的な会話は1本の電話で行われ、あなたと友人は相手の話が終わるのを待たずに(どちらかが中断されるのは失礼だと思うかもしれませんが!)じっくりと話すことができ、それぞれが相手の話している内容を覚えています。このように、WebSocketはより流動的で自然な会話を可能にする。それがライブチャットのやりとりであれ、文書での共同作業であれ、ライブストリームの配信であれ、マルチプレイヤーゲームであれ。
WebSocketのセキュリティに関する懸念
WebSocketのリアルタイムの双方向データ転送の可能性は、このプロトコルが非常に強力であることの一部ですが、潜在的に脆弱でもあります。他のネットワーク通信と同様に、WebSocketは次のようなセキュリティ攻撃の影響を受けやすい:
マンインザミドル (MitM):攻撃者がクライアントとサーバー間の接続を傍受し、通信を盗聴してデータを改ざんする。
クロスサイトWebSocketハイジャック:この種の攻撃では、WebSocketの実装自体が悪用され、不正アクセスを許したりデータを盗んだりする。
サービス拒否(DoS):サーバーに接続要求が殺到し、サーバーが応答不能になり、リソースが枯渇した場合に発生する。
幸いなことに、WebSocket接続をセキュアにする方法がある:
セキュアWebSocketの使用
wss://)を使用して、クライアントとサーバー間で送信されるデータを暗号化する。適切な認証と認可の実装以下のようなトークンを使用して JSONウェブトークン(JWT)を使用することで、許可されたユーザーだけが WebSocket 接続にアクセスできるようになります。
入出力データの検証インジェクション攻撃を防ぐ
オリジンチェックハンドシェイクリクエストのヘッダが信頼できるソースからのものであることを確認する。
レート制限DoS攻撃を防止し、リソースを効率的に管理します。
WebSocketトラフィックのログと監視異常なアクティビティを検出し、潜在的なセキュリティ脅威にリアルタイムで介入する。
これを念頭に置いて、次のサンプル・アプリケーションを見てみましょう。 Vonage Voice APIと NCCO Connectアクションアクションを使用して WebSocket 接続を確立し、認証するサンプル・アプリケーションを見てみましょう。
サンプルアプリケーションセキュアなリアルタイム発信者エコー
このサンプル・アプリケーションでは Voice APIを使用して、着信コールに応答し、発信者に自分の声のエコーを聞かせます。NCCO アクションで作成され、JWT で認証された WebSocket 接続のパワーを活用しています。
アプリをローカルで実行するための完全なコードと README は GitHub の Vonage コミュニティ.
このアプリは、パケット数とバイト数を表示するStatsのウェブページを提供し、データ(発信者のVoice)がリアルタイムで双方向に送信されていることを示す。
A screenshot of the stats web page showing an open connection and the amount of transmitted data. The packets and bytes received and sent are identical because the data being transmitted is an echo.GitHubの GitHubのレポをご覧ください。サンプルアプリをエンド・ツー・エンドで実行するには Vonageアカウント.
NCCOとの安全なWebSocket接続の確立
A 呼制御オブジェクト(NCCO)は、JSONを使用して、Voice APIサーバーがWebhookに到達したときに取るアクションを指示します。サンプルアプリケーションで定義されている /webhooks/answerが返す次の NCCO は、サンプルアプリケーションで定義されている connect アクションを使用しています。 websocketタイプにルーティングするアクションを使用しています。これは、高忠実度の24 kHzリニアPCMサンプリングレートを使用して、WebSocket接続を介してリアルタイムの生のオーディオストリームを確立します:
ncco = [
{
"action": "talk",
"text": "We will now connect you to the echo server with advanced WebSocket features. Wait a moment then start speaking.",
},
{
"action": "connect",
"from": VONAGE_VIRTUAL_NUMBER,
"endpoint": [
{
"type": "websocket",
"uri": f"wss://{request.headers.get('host')}/socket",
"content-type": "audio/l16;rate=24000", # 24 kHz audio
"headers": {"X-Custom-Header": "demo-value"},
# Authorization configuration
"authorization": {
"type": "vonage" # Vonage will send JWT in Authorization header
},
}
],
},
]さらに websocketタイプは authorizationヘッダをサポートしており、Vonageが提供するJWTを 署名されたウェブフック.このヘッダ認証オプションは最初のリクエストハンドシェイクの一部である。
JWTはここでサーバーによって検証される:
# Get authorization header for authentication
auth_header = websocket.headers.get("authorization", "")
# Validate JWT if present
if auth_header.startswith("Bearer "):
token = auth_header.replace("Bearer ", "")
print("JWT validation: ===> Valid JWT token received")
verify_signature(token, VONAGE_SIGNATURE_SECRET)
print(
f"Valid signature: ===> token: {token} vs. signature secret: {VONAGE_SIGNATURE_SECRET}"
)
if not verify_signature(token, VONAGE_SIGNATURE_SECRET):
print("JWT validation: ===> Invalid JWT token received")
await websocket.close(code=1008, reason="Unauthorized")
returnこの検証ステップによって、未承認のクライアントが長寿命のコネクションを確立するのを防ぐことができる。WebSocketは長寿命のコネクションなので、認証はハンドシェイクの間に行われなければならない。を使用してJWT署名を検証することで、次のことが保証されます。 VONAGE_SIGNATURE_SECRETを使ってJWT署名を検証することで
リクエストの発信元は Vonage です。
ペイロードは改ざんされていない
許可されていないクライアントは即座に拒否される
バリデーションに失敗した場合、接続は 1008 ポリシー違反で接続が閉じられ、それ以上のやりとりができなくなります。
WebSocketでのリアルタイム・オーディオ処理
認証されると、接続が受け入れられ、2種類のメッセージの処理が開始される:
テキストフレーム:以下のような制御イベントに使用される。
websocket:connectedバイナリーフレーム:通話の生のオーディオデータを含む
この例では、単に音声を呼び出し側にエコーバックしていますが、アプリケーション・ロジックは通常ここに置かれます:
if "text" in message:
# Handle text messages (JSON commands/events)
data = json.loads(message["text"])
print(f"Received text: ===> {data}")
# Handle special commands
if data.get("event") == "websocket:connected":
print("WebSocket: ===> Connection established with Vonage")
elif "bytes" in message:
# Handle binary audio data
audio_data = message["bytes"]
active_connections[connection_id]["packets_received"] += 1
active_connections[connection_id]["bytes_received"] += len(audio_data)
# Echo audio back to caller
await websocket.send_bytes(audio_data)
active_connections[connection_id]["packets_sent"] += 1
active_connections[connection_id]["bytes_sent"] += len(audio_data)NCCOはオーディオフォーマット audio/l16;rate=24000を定義しているため)、追加のネゴシエーションなしで、ストリームを確実に処理または変換することができる。
なぜこのパターンが重要なのか
このサンプルコードでは このサンプルコードではこのサンプルコードは、実際には大したことはできませんが、より高度でセキュアなストリーミング音声アプリケーションを構築するための基礎となるパターンを提供しています。
例えば、以下のコードブロックを拡張して、他のタイプのコマンドやイベントのロジックを含めることができます。例えば clearコマンド を使うこともできます。あるいは notifyイベント アプリケーションのロジックを同期させて、録音を開始したり、オーディオが終了したら新しいプロンプトを再生したりすることができます。:
# Handle special commands
if data.get("event") == "websocket:connected":
print("WebSocket: ===> Connection established with Vonage")VonageがどのようにWebSocketを実装しているかについては、以下をご覧ください。 ドキュメント.
まとめ
WebSocketは、クライアントとサーバ間の持続的な双方向接続を可能にすることで、インスタントアップデートに対する考え方を根本的に変えます。このブログポストでは、このシフトがいかに待ち時間を短縮し、効率を向上させ、ライブチャット、ストリーミング、コラボレーションアプリケーションなどの最新のユースケースを解放するかを探った。
また、VonageがVoice APIとNCCOアクションを使用して、このプロトコルの上にどのように構築しているかを見てみました。 connectアクションを使用しています。エンドポイントを活用することで websocketエンドポイントを活用することで、ライブ音声をアプリケーションに直接ストリーミングすることができます。
さらに重要なことは、Vonage authorizationヘッダを使って、サーバーが最初のハンドシェイクの間に WebSocket 接続を検証し、セキュアにする方法を紹介した。
認証を組み込んだNCCO主導のWebSocket接続のパターンは、AIを搭載したアシスタントからリアルタイムの音声処理パイプラインまで、より高度な音声体験を構築するための強力で安全な基盤を提供します。
その他の資料
WebSocket経由でDialogflowチャットボットに電話を統合する:このチュートリアルでは、Vonage Voice APIを使用して、Dialogflowボットの例から始めて、提供されたサンプル参照コードを使用して電話から対話するのに役立ちます。
Spring BootでWebSocketサーバーを作る:このチュートリアルでは、バイナリメッセージとテキストメッセージの両方を受信できるWebSocketサーバーをSpring Bootを使って作成する方法を学びます。
リアルタイム品質モニタリングでユーザーのVideo体験を向上させる:MOSはビデオ通話の優れたビデオ品質指標です。Vonage Videoがどのようにこれを使用してユーザー体験を向上させているかをご覧ください。
Laravel、Livewire、Reverb、Echoを使ったRCSメッセージング:Laravel、Livewire、Vonageを使って、JavaScript不要のリアルタイムRCSメッセンジャーを構築します。
ご質問がある場合、またはあなたが作っているものを共有したい場合は、こちらをクリックしてください。
登録する 開発者ニュースレター
フォローする X(旧ツイッター)最新情報
チュートリアルを見る YouTubeチャンネル
LinkedInの LinkedIn の Vonage デベロッパーページ
最新の開発者向けニュース、ヒント、イベント情報をお届けします。