cpp

Веб-сервер на Go

С помощью Go можно создавать не только консольные приложения, но и запустить веб-сервер, отслеживающий запросы на каком-либо порту. В зависимости от строки запроса веб-сервер отправляет в качестве ответа информацию, соответствующую запросу.

Примечание

Запуск и остановка веб-сервера

Запустить веб-сервер позволяет функция ListenAndServe() из пакета net/http. Формат функции:

// import "net/http"
http.ListenAndServe(addr string, handler http.Handler) error

В первом параметре указывается название хоста и/или номер порта через двоеточие. Во втором параметре передается объект, реализующий интерфейс Handler, который содержит объявление метода ServeHTTP():

type Handler interface {
   ServeHTTP(ResponseWriter, *Request)
}

Метод ServeHTTP() принимает объект ResponseWriter с настройками ответа сервера и указатель на объект структуры Request (см. разд. 19.14) с параметрами запроса.

После успешного запуска сервера выполняется бесконечное ожидание запросов. При получении запроса будет вызван метод ServeHTTP(), внутри которого нужно отправить ответ, используя методы объекта ResponseWriter. Чтобы прервать выполнение бесконечного цикла, следует в командной строке нажать комбинацию клавиш <Ctrl>+<C>. Если сервер запустить не удалось или сервер остановлен, то функция ListenAndServe() вернет объект ошибки.

Запустим сервер на порту 3000 и при любом запросе отправим ответ, который будет выведен в окне веб-браузера в формате HTML (листинг 20.1).

Листинг 20.1. Запуск веб-сервера

package main

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

type MyHandler struct {
   Msg string
}
func (h MyHandler) ServeHTTP(rw http.ResponseWriter, r *http.Request) {
   // Добавляем заголовок с типом содержимого ответа
   rw.Header().Add("Content-Type", "text/html; charset=UTF-8")
   // Название сервера
   rw.Header().Add("Server", "MyServer 1.0")
   // Ответ сервера
   fmt.Fprintln(rw, h.String())
}
func (h MyHandler) String() string {
   return h.Msg + time.Now().Format("02.01.2006 15:04:05")
}
func main() {
   handler := MyHandler{"Привет, мир!<br>"}
   err := http.ListenAndServe(":3000", handler)
   if errors.Is(err, http.ErrServerClosed) {
      fmt.Println("ErrServerClosed")
   } else {
      fmt.Println(err)
   }
}

Открываем командную строку и запускаем веб-сервер:

C:\book\test>go run main.go

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

Теперь открываем веб-браузер и в адресной строке вводим: http://localhost:3000/. Должно отобразиться приветствие:

Привет, мир!
05.05.2022 22:18:45

Посмотрим на заголовки ответа сервера:

HTTP/1.1 200 OK
Content-Type: text/html; charset=UTF-8
Server: MyServer 1.0
Date: Thu, 05 May 2022 19:30:04 GMT
Content-Length: 45

Заголовки Content-Type и Server мы добавили самостоятельно. Остальные заголовки были сформированы автоматически. Если мы вставим символы комментариев перед инструкцией:

rw.Header().Add("Content-Type", "text/html; charset=UTF-8")

то по умолчанию будет отправлен следующий заголовок:

Content-Type: text/plain; charset=utf-8

В результате ответ будет обработан веб-браузером как обычный текст и в окне веб-браузера мы получим следующий результат:

Привет, мир!<br>05.05.2022 22:35:53
На заметку

Учебник Go (Golang)
Учебник Go (Golang) в формате PDF

Помощь сайту

ЮMoney (Yandex-деньги): 410011140483022

ПАО Сбербанк:
Счет: 40817810855006152256
Реквизиты банка:
Наименование: СЕВЕРО-ЗАПАДНЫЙ БАНК ПАО СБЕРБАНК
Корреспондентский счет: 30101810500000000653
БИК: 044030653
КПП: 784243001
ОКПО: 09171401
ОКОНХ: 96130
Скриншот реквизитов

cpp