Maison  >  Article  >  développement back-end  >  Comment arrêter progressivement un serveur HTTP après une réponse ?

Comment arrêter progressivement un serveur HTTP après une réponse ?

Linda Hamilton
Linda Hamiltonoriginal
2024-10-31 04:19:30578parcourir

How to Gracefully Shut Down an HTTP Server After a Response?

Arrêter gracieusement le serveur HTTP après réponse

Problème

Lors de l'utilisation d'un serveur HTTP local pour capturer des jetons d'accès OAuth pour une intégration d'API Instagram, le Le serveur doit être arrêté une fois le jeton affiché à l'utilisateur. Cependant, tenter d'arrêter manuellement le serveur à l'aide de srv.Shutdown() entraîne une erreur :

Httpserver: ListenAndServe() error: http: Server closed
http: panic serving [::1]:61793: runtime error: invalid memory address or nil pointer dereference

Analyse

L'erreur se produit car le serveur HTTP traite toujours d'autres requêtes pendant que showTokenToUser Le gestionnaire tente de l'arrêter.

Solution

Pour arrêter correctement le serveur HTTP après avoir terminé la demande de rappel :

1. Utilisez Context.WithCancel()

Utilisez context.WithCancel() pour créer un contexte qui peut être annulé manuellement. Transmettez ce contexte au serveur HTTP lors de son démarrage.

2. Arrêtez le serveur en douceur

Dans le gestionnaire de rappel showTokenToUser, appelez srv.Shutdown(ctx) pour arrêter le serveur en douceur. ctx est le contexte annulé transmis au serveur.

Code

<code class="go">package main

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

func main() {
    ctx, cancel := context.WithCancel(context.Background())
    http.HandleFunc("/instagram/callback", func(w http.ResponseWriter, r *http.Request) {
        showTokenToUser(w, r, ctx)
    })

    srv := &http.Server{Addr: ":8000"}
    go func() {
        if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
            log.Printf("httpserver: ListenAndServe() error: %s", err)
        }
    }()

    <-ctx.Done()

    // Gracefully shut down the server
    if err := srv.Shutdown(context.Background()); err != nil && err != context.Canceled {
        log.Println(err)
    }
}

func showTokenToUser(w http.ResponseWriter, r *http.Request, ctx context.Context) {
    io.WriteString(w, fmt.Sprintf("Your access token is: %v", r.URL.Query().Get("code")))
    cancel()
}</code>

Cette solution garantit que le serveur HTTP est arrêté en douceur une fois la demande de rappel terminée, sans provoquer d'erreurs ni d'interruption connexions continues.

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