リアルタイム通信サーバーのプッシュ メカニズム EventSource (SSE) の紹介と Go の実装例

導入

Content-Type:text/event-streamリクエスト ヘッダーを見たことがあるかどうかはわかりませんがHTML5、これはサーバー プッシュによるリアルタイム通信を可能にするEventSource強力な機能です。API

と比較するとWebSocketEventSourceシンプルで信頼性の高い一方向通信メカニズム (サーバー -> クライアント) が提供され、実装が簡単で、多くのリアルタイム アプリケーション シナリオに適しています。

EventSourceこの記事では、 の簡単な使い方、 との比較、メリットとデメリットを紹介しWebSocket、最後にまとめます。

イベントソース

クライアントはサーバーからの「ストリーム」を購読し、サーバーまたはクライアントが「ストリーム」を閉じるまでサーバーはクライアントにメッセージを送信できるため、 とも呼ばれEventSourceますSSE(server-sent-event)

  • EventSourceクライアントとサーバー間の永続的な一方向通信接続を確立するために使用されるHTML5アイテムです。API
  • これはHTTPプロトコルに基づいており、サーバー プッシュを通じてリアルタイムのイベント通知をクライアントに送信します。
  • クライアントはイベントをキャプチャし、イベント リスナーを追加することで適切なアクションを実行します。

使い方が簡単

例:
サーバー側は を使用してGoルートを作成し/events、クライアントがEventSourceオブジェクトを通じてルートに接続すると、サーバーはイベントのストリームを継続的に送信します (2 秒ごとに 1 つのイベント)。クライアントのHTMLページにオブジェクトJavaScriptが作成され、受信したイベント データがイベントを通じてページに追加されます。エラーが発生した場合、クライアントは接続を閉じます。EventSourceonmessageEventSource

ファイル構造は次のとおりです

程序目录
	- main.go
	- c1.html

サービスに行く

package main

import (
	"fmt"
	"gopkg.in/antage/eventsource.v1"
	"log"
	"net/http"
	"time"
)

func main() {
    
    
	es := eventsource.New(nil, nil)
	defer es.Close()

	http.Handle("/", http.FileServer(http.Dir("./")))
	http.Handle("/events", es)
	go func() {
    
    
		for {
    
    
			// 每2秒发送一条当前时间消息,并打印对应客户端数量
			es.SendEventMessage(fmt.Sprintf("hello, now is: %s", time.Now()), "", "")
			log.Printf("Hello has been sent (consumers: %d)", es.ConsumersCount())
			time.Sleep(2 * time.Second)
		}
	}()

	log.Println("Open URL http://localhost:8080/ in your browser.")
	err := http.ListenAndServe(":8080", nil)
	if err != nil {
    
    
		log.Fatal(err)
	}
}

フロントエンドHTML

<!DOCTYPE html>
<html>
<head>
    <title>SSE test</title>
    <script type="text/javascript">
        window.addEventListener("DOMContentLoaded", function () {
      
      
            var evsrc = new EventSource("http://localhost:8080/events");
            var msgEvent = function (ev) {
      
      
                document.getElementById("log")
                    .insertAdjacentHTML("beforeend", "<li>" + ev.data + "</li>");
            }
			evsrc.onmessage = msgEvent;
			//evsrc.addEventListener("message", msgEvent)
            evsrc.onerror = function (ev) {
      
      
                console.log("readyState = " + ev.currentTarget.readyState);
            }
        })
    </script>
</head>
<body>
<h1>SSE test</h1>
<div>
    <ul id="log">
    </ul>
</div>
</body>
</html>

サービスが開始されたら、http://localhost:8080/c1.htmlにアクセスすると、次のページが表示されます。
ここに画像の説明を挿入します

WebSocketとの比較

イベントソースの利点

  • 使いやすさ:複雑なハンドシェイクを行わずにEventSource、シンプルな標準ベースのHTTPプロトコルを使用します。
  • 自動再接続:EventSource接続が中断された後に自動的に再接続するための再接続メカニズムが組み込まれています。
  • 軽量:EventSourceロング ポーリング メカニズムを使用するため、消費するリソースが比較的少なく、低帯域幅環境に適しています。
  • クロスドメインのサポート:EventSourceクロスドメイン環境での通信を許可し、適切な応答ヘッダーを通じて異なるドメインからのクライアント接続を許可します。

イベントソースの欠点

  • 一方向通信:EventSourceサーバーからクライアントへの一方向通信のみをサポートし、クライアントからサーバーへのリアルタイムの対話を実現できません。
  • 下位ブラウザのサポート: 最新のブラウザでは広くサポートされていますがEventSource、一部の古いブラウザでは完全にはサポートされていない場合があります。

WebSocket の利点

  • 双方向通信:WebSocket全二重通信をサポートし、クライアントとサーバーは同じ接続上で双方向のデータ交換を行うことができます。
  • リアルタイムと効率性:WebSocket低遅延と効率的なパフォーマンスにより、高速なリアルタイム応答を必要とするアプリケーションに適しています。
  • 大規模なアプリケーション: WebSocket は、オンライン ゲーム、共同編集などの複雑で大規模なリアルタイム アプリケーションに適しています。

WebSocket の欠点

  • 複雑さ: WebSocket プロトコルのハンドシェイク プロセスは比較的複雑であり、サーバーとクライアントが特定のプロトコル ロジックを実装する必要があります。
  • ファイアウォールやプロキシ サーバーの通過が困難: WebSocket の特殊なプロトコルは、ファイアウォールやプロキシ サーバーによって制限される場合があります。

要約する

EventSourceは、リアルタイム通信のためのシンプルで信頼性の高いサーバー プッシュ メカニズムを提供するHTML5強力なものです。API

と比較するとWebSocketEventSourceそのシンプルさと使いやすさ、自動再接続、軽量、クロスドメインのサポートが利点です。ただし、一方向通信や下位ブラウザのサポートなど、いくつかの制限もあります。対照的に、WebSocket双方向通信、大規模なアプリケーション、リアルタイム要件の高いシナリオには適していますが、その複雑さとファイアウォールを通過する際の課題も考慮する必要があります。

全体として、これは、リアルタイム株価、リアルタイム チャット、リアルタイム通知など、多くのリアルタイム アプリケーション シナリオに適した非常にEventSource便利なツールです。APIこれは、サーバー プッシュ接続を確立し、リアルタイムの更新と通知を可能にする、シンプルで信頼性の高い方法を提供します。EventSourceこれは、アプリケーションでサーバーからクライアントへのデータの一方向のプッシュのみが必要な場合に適しています。ただし、双方向通信またはより高度なリアルタイム機能が必要な場合は、WebSocketより適切な可能性があります。

参考

おすすめ

転載: blog.csdn.net/DisMisPres/article/details/130539861