Rumah > pembangunan bahagian belakang > Golang > Bagaimanakah Saya Boleh Mengakses Soket Pendasar bagi Respons net/http dalam Go?

Bagaimanakah Saya Boleh Mengakses Soket Pendasar bagi Respons net/http dalam Go?

DDD
Lepaskan: 2024-11-07 10:36:03
asal
384 orang telah melayarinya

How Can I Access the Underlying Socket of a net/http Response in Go?

Mendapatkan semula Soket Pendasar bagi net/http Response

Dalam bidang pengaturcaraan rangkaian dengan pakej net/http Go, kadangkala kita mungkin perlu mengakses terus yang mendasari sambungan rangkaian(net.Conn).

Pernyataan Masalah

Pemaju cuba menyediakan fail menggunakan net/http, tetapi menghadapi masalah: memerlukan akses kepada soket asas http.ResponseWriter dalam fungsi pengendali ( net.Conn) untuk membuat panggilan sistem khusus platform.

Penyelesaian

Dalam Go 1.13 dan ke atas, net.Conn boleh disimpan dalam konteks permintaan dengan mengikut langkah berikut:

  • Gunakan fungsi SaveConnInContext untuk menyimpan bersih .Conn disimpan ke konteks permintaan.
  • Dapatkan semula net.Conn daripada permintaan menggunakan fungsi GetConn.

Sebelum keluaran ini, terdapat dua alternatif:

Gunakan rentetan alamat jauh

Untuk mendengar pada port TCP Untuk pelayan , net.Conn.RemoteAddr().String() adalah unik untuk setiap sambungan dan boleh digunakan sebagai kunci kepada peta sambungan global.

Override net.Listener.Accept()

Untuk pelayan mendengar pada soket UNIX, kami boleh mengatasi net.Listener.Accept() untuk Gunakan deskriptor fail untuk kembali nilai yang lebih unik.

Contoh Kod

Pergi 1.13 dan ke atas

<code class="go">// SaveConnInContext stores the net.Conn in the request context.
func SaveConnInContext(ctx context.Context, c net.Conn) context.Context {
  return context.WithValue(ctx, ConnContextKey, c)
}

// GetConn retrieves the net.Conn from the request context.
func GetConn(r *http.Request) net.Conn {
  return r.Context().Value(ConnContextKey).(net.Conn)
}</code>
Salin selepas log masuk

Untuk sambungan TCP

<code class="go">// ConnStateEvent handles connection state events.
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())
  }
}

// GetConn retrieves the net.Conn from a map using the remote address as a key.
func GetConn(r *http.Request) net.Conn {
  return conns[r.RemoteAddr]
}</code>
Salin selepas log masuk

Untuk sambungan UNIX

<code class="go">// NewUnixListener creates a new UNIX listener with a modified Accept() method.
func NewUnixListener(path string) (net.Listener, error) {
  // ... (setup code)

  l, err := net.Listen("unix", path)
  if err != nil {
    return nil, err
  }

  return NewConnSaveListener(l), nil
}

// NewConnSaveListener wraps a listener and overrides the Accept() method.
func NewConnSaveListener(wrap net.Listener) net.Listener {
  return connSaveListener{wrap}
}

// remoteAddrPtrConn overrides the RemoteAddr() method to return a unique value.
type remoteAddrPtrConn struct {
  net.Conn
  ptrStr string
}

func (self remoteAddrPtrConn) RemoteAddr() net.Addr {
  return remoteAddrPtr{self.ptrStr}
}

// remoteAddrPtr implements the net.Addr interface.
type remoteAddrPtr struct {
  ptrStr string
}

func (remoteAddrPtr) Network() string {
  return ""
}

func (self remoteAddrPtr) String() string {
  return self.ptrStr
}

// Accept overrides the default Accept() method to store the net.Conn in a map.
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
}</code>
Salin selepas log masuk

Melalui kaedah ini, pembangun boleh mengakses soket asas http.ResponseWriter dengan mudah, membuka rangkaian pengendalian rangkaian tersuai untuk mereka.

Atas ialah kandungan terperinci Bagaimanakah Saya Boleh Mengakses Soket Pendasar bagi Respons net/http dalam Go?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

sumber:php.cn
Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan