Как принудительно закрыть соединение без ожидания полного ответа запроса?

Для принудительного закрытия соединения без ожидания полного ответа запроса в языке программирования Go можно воспользоваться пакетом net/http и методом CloseNotify().

Для начала, необходимо импортировать нужные пакеты:

import (
    "net/http"
    "time"
)

Затем, вы можете создать обработчик HTTP-запросов с помощью функции http.HandlerFunc, в котором будет вызываться метод CloseNotify() для проверки закрытия соединения:

func handler(w http.ResponseWriter, r *http.Request) {
    ctx := r.Context()
    cn, ok := w.(http.CloseNotifier).CloseNotify()

    go func() {
        <-cn
        // Действия при закрытии соединения
        // Пример: log.Println("Соединение закрыто")
    }()

    select {
    case <-time.After(time.Second * 5):
        // Ответ на запрос
        // Пример: fmt.Fprintln(w, "Привет, мир!")
    case <-ctx.Done():
        // Обработка отмены запроса
        // Пример: log.Println("Запрос отменен")
    }
}

В этом примере создается контекст запроса ctx, в котором можно проверить, не произошло ли закрытие соединения. Затем, с помощью CloseNotify() используется http.CloseNotifier для получения канала, который будет закрыт в случае закрытия соединения.

Затем, создается горутина, которая ожидает закрытия канала cn и выполняет необходимые действия при закрытии соединения.

В конце используется блок select для выбора одного из двух каналов - либо временного канала time.After() для ожидания ответа в течение 5 секунд, либо контекста запроса ctx.Done() для обработки отмены запроса.

Таким образом, при принудительном закрытии соединения без ожидания полного ответа запроса, горутина, ожидающая закрытия канала cn, будет завершена и можно будет выполнить соответствующие действия, например, записать в лог информацию об закрытии соединения.