Maison  >  Article  >  développement back-end  >  Comment accéder au socket sous-jacent dans la réponse net/http de Go ?

Comment accéder au socket sous-jacent dans la réponse net/http de Go ?

Barbara Streisand
Barbara Streisandoriginal
2024-11-04 12:42:29675parcourir

How Do I Access the Underlying Socket in Go's net/http Response?

Obtention du socket sous-jacent dans la réponse net/http de Go

Le package net/http de Go fournit un cadre pratique pour créer des serveurs HTTP. Cependant, il peut arriver que vous ayez besoin d'accéder au socket sous-jacent du flux de réponse. Cet article répond à ce besoin en explorant différentes approches pour récupérer la connexion socket.

Avant Go 1.13

Avant Go 1.13, l'obtention du socket sous-jacent nécessitait des techniques plus élaborées. Voici deux approches :

  1. Suivi basé sur les événements (connexions TCP uniquement) :
    Pour les connexions via des ports TCP, vous pouvez exploiter net.Listener. Gestionnaire d’événements ConnState pour suivre les connexions actives et leurs sockets associés. Ces informations peuvent être stockées dans une carte globale pour une récupération ultérieure.

    <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>
  2. Remplacement de l'écouteur (sockets Unix) :
    Les sockets Unix nécessitent un processus plus complexe. approche car ils manquent d’identifiants uniques pour chaque connexion. Une solution consiste à remplacer la méthode net.Listener.Accept pour attribuer des chaînes uniques à chaque connexion et à les utiliser comme clés pour stocker les informations sur les sockets.

    <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 et Au-delà

Avec la sortie de Go 1.13, une solution plus simple est disponible :

  1. Stockage basé sur le contexte :
    À partir de Go 1.13, net.Conn peut être stocké dans le contexte de la requête HTTP. Cela fournit un moyen propre et efficace d'accéder à la connexion socket.

    <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>

En comprenant ces techniques, vous pouvez récupérer efficacement le socket sous-jacent dans vos gestionnaires de réponse net/http, permettant ainsi des opérations et fonctionnalités spécifiques à la plate-forme.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn