Go の net/http レスポンスで基礎となるソケットを取得する
Go の net/http パッケージは、HTTP サーバーを構築するための便利なフレームワークを提供します。ただし、応答ストリームの基礎となるソケットへのアクセスが必要な状況が発生する場合があります。この記事では、ソケット接続を取得するためのさまざまなアプローチを検討することで、このニーズに対処します。
Go 1.13 より前
Go 1.13 より前では、基になるソケットを取得するには、より複雑なテクニックが必要でした。ここでは 2 つのアプローチを示します:
イベントベースの追跡 (TCP 接続のみ):
TCP ポート経由の接続の場合、net.Listener を利用できます。アクティブな接続とそれに関連するソケットを追跡するための ConnState イベント ハンドラー。この情報は、後で取得できるようにグローバル マップに保存できます。
<code class="go">var conns = make(map[string]net.Conn) func ConnStateEvent(conn net.Conn, event http.ConnState) { if event == http.StateActive { conns[conn.RemoteAddr().String()] = conn } else if event == http.StateHijacked || event == http.StateClosed { delete(conns, conn.RemoteAddr().String()) } } func GetConn(r *http.Request) (net.Conn) { return conns[r.RemoteAddr] }</code>
リスナー オーバーライド (Unix ソケット):
Unix ソケットには、より複雑なソケットが必要です。各接続に一意の識別子がないため、このアプローチは困難です。 1 つの解決策は、net.Listener.Accept メソッドをオーバーライドして各接続に一意の文字列を割り当て、それらをソケット情報を保存するためのキーとして使用することです。
<code class="go">func NewConnSaveListener(wrap net.Listener) (net.Listener) { return connSaveListener{wrap} } func (self connSaveListener) Accept() (net.Conn, error) { conn, err := self.Listener.Accept() ptrStr := fmt.Sprintf("%d", &conn) conns[ptrStr] = conn return remoteAddrPtrConn{conn, ptrStr}, err } func GetConn(r *http.Request) (net.Conn) { return conns[r.RemoteAddr] }</code>
Go 1.13 および
を超えて、Go 1.13 のリリースにより、より簡単なソリューションが利用可能になりました:
コンテキストベースのストレージ:
Go 1.13 以降では、net.Conn を HTTP リクエストのコンテキストに保存できるようになりました。これにより、ソケット接続にアクセスするためのクリーンで効率的な方法が提供されます。
<code class="go">type contextKey struct { key string } var ConnContextKey = &contextKey{"http-conn"} func SaveConnInContext(ctx context.Context, c net.Conn) (context.Context) { return context.WithValue(ctx, ConnContextKey, c) } func GetConn(r *http.Request) (net.Conn) { return r.Context().Value(ConnContextKey).(net.Conn) }</code>
これらのテクニックを理解することで、net/http 応答ハンドラーで基礎となるソケットを効果的に取得し、カスタムを有効にすることができます。操作とプラットフォーム固有の機能。
以上がGo の net/http 応答の基になるソケットにアクセスするにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。