首页 > 解决方案 > 在浏览器关闭时关闭 Go 服务器

问题描述

我在 Go 中编写了一个小型支票簿分类帐,作为在 localhost 中运行的服务器,并将默认浏览器打开到小型 Web 应用程序前端(https://bitbucket.org/grkutzmd/checks-and-balances)。

为了在浏览器选项卡关闭时自动关闭服务器,我让浏览器每隔几秒调用一次“心跳”URL。如果该心跳未到达,则服务器用于(*Server) Shutdown停止运行。

有没有办法使用上下文(https://golang.org/pkg/context/)做同样的事情?我通过观看JustForFunc 的这一集了解到,如果客户端取消请求,将通知传递给处理程序的上下文。

标签: goshutdown

解决方案


您可以利用服务器发送的事件,而不是每隔一段时间发送一个“心跳”请求。

服务器发送事件是一种 Web 技术,其中浏览器发出 HTTP 请求并保持连接打开以接收来自服务器的事件。这可以通过在与事件源的连接关闭时关闭服务器来替代您对重复心跳请求的需求。

这是 Go 中的基本服务器实现:

package main

import (
    "fmt"
    "log"
    "net/http"
    "time"
)

func main() {
    http.HandleFunc("/heartbeat", func(w http.ResponseWriter, r *http.Request) {
        w.Header().Set("Content-Type", "text/event-stream")
        w.Header().Set("Cache-Control", "no-cache")
        w.Header().Set("Connection", "keep-alive")

        flusher, ok := w.(http.Flusher)
        if !ok {
            http.Error(w, "your browser doesn't support server-sent events")
            return
        }

        // Send a comment every second to prevent connection timeout.
        for {
            _, err := fmt.Fprint(w, ": ping")
            if err != nil {
                log.Fatal("client is gone, shutting down")
                return
            }
            flusher.Flush()
            time.Sleep(time.Second)
        }
    })
    fmt.Println(http.ListenAndServe(":1323", nil))
}

有关客户端的指南,请参阅使用服务器发送的事件


推荐阅读