Проверьте подключение к Интернету из приложения

Мне нужно проверить, подключен ли пользователь к Интернету, прежде чем я смогу продолжить.

Я поражаю конечную точку с помощью HttpClient следующим образом:

client := &http.Client{}
req, _ := http.NewRequest("GET", url, nil)
req.SetBasicAuth(username, password)
res, err := client.Do(req)

if err != nil {
    fmt.Println(err)
    ui.Failed("Check your internet connection")
}

1) Мне нужно показывать пользователю четкие сообщения, если в этом случае пользователь не подключен к Интернету, выведите "Пожалуйста, проверьте подключение к Интернету"

2) Если сервер не отвечает и получает 504 неисправных шлюза, выведите "504 Bad gateway"

Может кто-нибудь помочь, как действовать и различать эти два сценария, и я хотел бы отображать только простые сообщения, а не все сообщения об ошибках, полученные от сервера.

2 ответа

Решение

Проверить наличие установленного интернет-соединения не так просто, как сделать один HTTP-запрос к произвольному URL, как предлагает Иван де ла Бельдад. Это может привести к сбою по ряду причин, ни одна из которых не остановит вас от того, что вы на самом деле намереваетесь сделать с соединением. Назвать несколько:

  • clients3.google.com может быть намеренно заблокирован локальной сетью (брандмауэр, корпоративный или школьный прокси-сервер) или любой сетью на маршруте (например, Great Firewall of China)
  • clients3.google.com может быть недоступен для некоторых клиентов из-за перебоев в работе сети
  • clients3.google.com сам может заблокировать клиента по любой причине (возможно, непреднамеренно)
  • clients3.google.com может быть отключен
  • порты 80 и 443 могут работать нормально, но все остальные порты заблокированы дерьмовым отелем / кафе wifi
  • дерьмовый отель / кафе wifi предоставляет клиентам поддельные сертификаты TLS, поэтому HTTPS-запросы во многих случаях не выполняются

Таким образом, вместо того, чтобы полагаться на один произвольный HTTP-запрос, гораздо лучше отправить какой-либо тест на жизнеспособность любым службам, которые вы действительно хотите использовать.

Если ваше приложение хочет взаимодействовать с API, проверьте, есть ли конечная точка состояния или состояния, которую вы можете вызвать. Если нет, поищите какой-нибудь дешевый неоператор. И старайтесь не говорить пользователям просто "проверить их интернет-соединение". Постарайтесь хотя бы объяснить, почему ваше приложение приходит к выводу, что может возникнуть проблема: "Мы не можем подключиться к Twitter прямо сейчас. Если вы подключены к Интернету, попробуйте еще раз через несколько минут", гораздо лучше.

Если вы действительно хотите проверить, доступен ли сам Интернет, я бы предложил сделать DNS-запрос нескольким DNS-серверам в Интернете. DNS вряд ли будет заблокирован с помощью локальных политик и дешевле, чем HTTP-запросы. Выбирайте ваши DNS-запросы с умом и будьте готовы к ответам NXDOMAIN.

Чтобы проверить, подключены ли вы к Интернету, вы можете использовать это:

func connected() (ok bool) {
    _, err := http.Get("http://clients3.google.com/generate_204")
    if err != nil {
        return false
    }
    return true
}

И чтобы получить код состояния, вы можете получить его от res.StatusCode, Конечный результат будет примерно таким:

if !connected() {
    ui.Failed("Check your internet connection")
}

client := &http.Client{}
req, _ := http.NewRequest("GET", url, nil)
req.SetBasicAuth(username, password)
res, _ := client.Do(req)

if res.StatusCode == 504 {
    ui.Failed("504 Bad gateway")
}

(Я игнорирую другие ошибки, которые вы должны обязательно проверить)

Другие вопросы по тегам