Rumah  >  Artikel  >  pembangunan bahagian belakang  >  Bagaimana untuk Mematikan Pelayan HTTP Go dengan Anggun Selepas Mengembalikan Respons?

Bagaimana untuk Mematikan Pelayan HTTP Go dengan Anggun Selepas Mengembalikan Respons?

DDD
DDDasal
2024-10-28 19:12:29145semak imbas

How to Gracefully Shut Down a Go HTTP Server After Returning a Response?

Mematikan Pelayan HTTP Selepas Memulangkan Respons

Dalam senario ini, anda telah membina bot baris arahan Go yang berinteraksi dengan API Instagram. Untuk mendapatkan token akses, anda memulakan pelayan HTTP tempatan untuk menangkap URI ubah hala. Walau bagaimanapun, anda menghadapi masalah semasa cuba menutup pelayan secara manual selepas mendapatkan semula token akses.

Masalah:

Ralat "Pelayan Ditutup" dan "Alamat Memori Tidak Sah" Berlaku Semasa Mematikan Pelayan

Analisis:

Ralat yang anda hadapi menunjukkan bahawa pelayan HTTP sedang ditutup lebih awal sebelum semua sambungan ditutup dengan baik. Ini boleh berlaku disebabkan oleh tingkah laku tak segerak dalam pengendali HTTP dan proses penutupan pelayan.

Penyelesaian 1: Menggunakan Context.WithCancel:

Pertimbangkan untuk menggunakan context.WithCancel untuk mencipta konteks yang boleh dibatalkan apabila token akses diambil semula. Hantarkan konteks ini kepada pengendali HTTP dan gunakan CancelFunc untuk menutup pelayan dengan anggun apabila konteks ditutup.

<code class="go">package main

import (
    "context"
    "io"
    "log"
    "net/http"
)

func main() {
    ctx, cancel := context.WithCancel(context.Background())

    http.HandleFunc("/quit", func(w http.ResponseWriter, r *http.Request) {
        io.WriteString(w, "Bye\n")
        cancel()
    })
    http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
        io.WriteString(w, "Hi\n")
    })

    srv := &http.Server{Addr: ":8080"}
    go func() {
        err := srv.ListenAndServe()
        if err != http.ErrServerClosed {
            log.Println(err)
        }
    }()

    <-ctx.Done()

    err := srv.Shutdown(context.Background())
    if err != nil {
        log.Println(err)
    }

    log.Println("done.")
}</code>

Penyelesaian 2: Menggunakan Konteks Yang Sama Merentas Fungsi:

Anda juga boleh menggunakan konteks yang sama merentas berbilang pengendali HTTP dan fungsi utama untuk memastikan semua fungsi dimaklumkan apabila pelayan harus ditutup.

<code class="go">package main

import (
    "context"
    "io"
    "log"
    "net/http"
)

func main() {
    ctx, cancel := context.WithCancel(context.Background())
    http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
        io.WriteString(w, "Hi\n")
    })
    http.HandleFunc("/quit", func(w http.ResponseWriter, r *http.Request) {
        io.WriteString(w, "Bye\n")
        cancel()
    })
    srv := &http.Server{Addr: ":8080"}
    go func() {
        if err := srv.ListenAndServe(); err != nil {
            log.Printf("Httpserver: ListenAndServe() error: %s", err)
        }
    }()
    <-ctx.Done()

    if err := srv.Shutdown(ctx); err != nil && err != context.Canceled {
        log.Println(err)
    }
    log.Println("done.")
}</code>

Kesimpulan:

Dengan menggunakan konteks.DenganBatal atau lulus konteks yang sama merentas pelbagai fungsi, anda boleh memastikan bahawa pelayan HTTP ditutup dengan anggun selepas semua sambungan telah ditutup. Ini akan menghalang ralat yang sedang anda hadapi.

Atas ialah kandungan terperinci Bagaimana untuk Mematikan Pelayan HTTP Go dengan Anggun Selepas Mengembalikan Respons?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

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