Завершение работы сервера Go в браузере close - PullRequest
0 голосов
/ 04 июня 2018

Я написал небольшую книгу чековой книжки в Go как сервер, который работает на localhost и открывает браузер по умолчанию для небольшого веб-приложения (https://bitbucket.org/grkuntzmd/checks-and-balances).

Для автоматического выключения сервера, когда браузервкладка закрыта, браузер вызывает каждые несколько секунд URL-адрес пульса. Если этот пульс не поступает, сервер использует (*Server) Shutdown для остановки работы.

Есть лиспособ сделать то же самое, используя контексты (https://golang.org/pkg/context/)? Насколько я понимаю, наблюдая этот эпизод JustForFunc, о том, что контекст, переданный обработчику, будет уведомлено, если клиент отменит запрос.

Ответы [ 2 ]

0 голосов
/ 04 июня 2018

Открыть подключение к веб-сокету со страницы.На сервере закройте выход из веб-сокета:

func wsHandler(w http.ResponseWriter, r *http.Request) {
    conn, err := upgrader.Upgrade(w, r, nil)
    if err != nil {
        log.Println(err)
        return
    }
    defer c.Close()

    // Shutdown on exit from handler
    defer server.Shutdown(context.Background())

    // Read  messages from client. NextReader returns an error
    // when the client shuts down.
    for {
        if _, _, err := c.NextReader(); err != nil {
            break
        }
    }
 }

Добавьте эту строку кода в клиентское приложение:

 var conn = new WebSocket("ws://" + document.location.host + "/ws");

Убедитесь, что conn имеет время жизни страницы.

Это несколько похоже на решение SSE, предложенное в другом ответе, но имеет преимущество работы в большем количестве браузеров.

Нет необходимости отправлять пульс, потому что он находится на локальном хосте.

0 голосов
/ 04 июня 2018

Вместо того, чтобы отправлять запрос «сердцебиение» так часто, вы можете воспользоваться событиями, отправленными сервером .

событиями, отправляемыми сервером, является веб-технология, в которой браузер создает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))
}

См. используя отправленные сервером события для руководства на стороне клиента.

...