Go предоставляет набор очень простых стандартов для создания веб-серверов. Просто вызовите функцию ListenAndServe в пакете net/http и передайте сетевой адрес и процессор, ответственный за обработку. Библиотека net/http реализует интерфейсы клиента и сервера в полном наборе http-сервисов. На основании этого вы можете легко инициировать HTTP-запросы или предоставлять HTTP-сервисы внешнему миру.
Примечание 1. Если сетевой адрес пуст, для сетевого подключения по умолчанию используется порт 80 hhtp. Если параметр процессора равен нулю, используется мультиплексор по умолчанию DefaultServeMux.
После получения запроса пользователя мультиплексор определяет, какой процессор использовать для обработки запроса, на основе запрошенного URL-адреса, а затем перенаправляет соответствующий процессор для обработки запроса.
http.HandleFunc — это мультиплексор, который направляет запросы к указанному обработчику на основе URL-адреса. Обработчик используется для обработки запросов и предоставления ответов. Более строго говоря, он используется для чтения тела запроса, записи полей ответа (заголовков ответов), соответствующих запросу, в ResponseWriter и последующего возврата:
Что такое Хэндлер. Это интерфейс, определенный в net/http/server.go:
type Handler interface { ServeHTTP(ResponseWriter, *Request) }
Другими словами, все те, кто реализует метод ServerHTTP, являются обработчиками. Обратите внимание на параметры метода ServerHTTP: интерфейс http.ResponesWriter и указатель запроса.
В комментариях Хэндлера дано несколько основных указаний:
Обработчик используется для ответа на HTTP-запрос. Метод интерфейса ServerHTTP следует использовать для записи заголовка ответа и данных, на которые необходимо ответить, в ResponseWriter, а затем возврата.
Интерфейс ResponseWriter используется для создания HTTP ответ и отправляет заголовок ответа и данные ответа клиенту через сетевую ссылку.
// A ResponseWriter interface is used by an HTTP handler to
// construct an HTTP response.
//
// A ResponseWriter may not be used after the Handler.ServeHTTP method
// has returned.
type ResponseWriter interface {
Header() Header
Write([]byte) (int, error)
WriteHeader(statusCode int)
}
Этот интерфейс имеет 3 метода:
type Header map[string][]string
В Go есть функция HandleFunc(), что означает использование функции второго параметра в качестве обработчика для обработки запроса соответствующего URL-пути. Первый параметр HandleFunc относится к пути запроса, а второй параметр — это тип функции, указывающий, что необходимо обработать для этого запроса. Вместо обработки сложной логики она обрабатывается непосредственно DefaultServeMux, как показано в исходном коде:
func HandleFunc(pattern string, handler func(ResponseWriter, *Request)) {
DefaultServeMux.HandleFunc(pattern, handler)
}
Стандартная библиотека Golang net/http предоставляет интерфейсы, связанные с http-программированием, инкапсулируя сложные и тривиальные детали внутренних TCP-соединений и анализа сообщений. Пользователям нужно взаимодействовать только с двумя объектами: http.request и http.ResponseWriter.
Исходный код, эквивалентный адаптеру:
type HandlerFunc func(ResponseWriter, *Request)
// ServeHTTP calls f(w, r).
func (f HandlerFunc) ServeHTTP(w ResponseWriter, r *Request) {
f(w, r)
}
Создайте метод процессора 1:
1.type HandlerFunc func(ResponseWriter,*Request)
package main
import (
"fmt"
"net/http"
)
//Создаем функцию-обработчик
func indexHandler(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Hello world") //Ввод приветствия в файл wПисать world
}
func main() {
//Находим процессор по URL Первый параметр естьURL
http.HandleFunc("/", indexHandler)
//Порт веб-прослушивания, прослушивание на локальном хосте: порт 9090, используйте DefaluteServeMux
http.ListenAndServe(":9090", nil)
}
Запустите службу: запустите web.go
Запросить услугу:
Создайте метод процессора 1:Создайте свой собственныйHandler
package main
import (
"fmt"
"net/http"
)
//Объявляем структуру
type IndexHandler struct{}
//Привязываем метод ServeHTTP(....) интерфейса Handler к IndexHandler
func (this *IndexHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
fmt.Fprintln(w, «Я Мой Хэндлер»)
}
func main() {
//Создаем экземпляр IndexHandler
myHandler := IndexHandler{}
//обрабатываем запрос
http.Handle("/", &myHandler)
http.ListenAndServe(":9090", nil)
}
GO предоставляет метод NewServerMux, позволяющий нам самостоятельно создать мультиплексор:
func NewServeMux() *ServeMux
package main
import (
"fmt"
"net/http"
)
func sayHello(w http.ResponseWriter, r *http.Request) {
fmt.Fprintln(w, "Hello golang")
}
func main() {
myMux := http.NewServeMux()
myMux.HandleFunc("/", sayHello)
http.ListenAndServe(":9090", myMux)
}
GO предоставляет структуру сервера. Мы можем создать экземпляр сервера для настройки некоторых конфигураций сервера.
type Server struct {
Addr string // Определите адрес и порт, который прослушивает Служит. Если он пуст, по умолчанию он будет прослушивать порт 80.
Handler Handler // Деловая сторона, чей запрос обрабатывается, по умолчанию http.DefaultServeMux
TLSConfig *tls.Config // Дополнительная конфигурация TLS, обеспечивающая https-служить внешнему миру.
ReadTimeout time.Duration // Таймаут чтения клиентских запросов, включая тело запроса на чтение
ReadHeaderTimeout time.Duration // Таймаут чтения заголовков запроса, если пусто, используйте ReadTimeout, Если ни то, ни другое, тайм-аута нет.
WriteTimeout time.Duration // Служить таймаут ответа
IdleTimeout time.Duration // Тайм-аут простоя длинной ссылки
MaxHeaderBytes int // Максимальный размер заголовка клиентского запроса, по умолчанию — 1 МБ.
ConnState func(net.Conn, ConnState) // Укажите дополнительный метод обратного вызова при изменении статуса подключения клиента.
ErrorLog *log.Logger // Используется при возникновении ошибок подключения, исключений обработчиков или файловой системы. По умолчанию используется интерфейс регистратора стандартной библиотеки.
onShutdown []func() // Вызов метода срабатывает, когда Служить остановлено
}
На основе приведенной выше структуры сервера стандартная библиотека Golang предоставляет следующие сервисные интерфейсы:
func (srv *Server) Close() error // Немедленно закройте все активное прослушивание и все соединения, включая новые соединения, активные и простаивающие соединения.
func (srv *Server) ListenAndServe() error // Запустите Служить для мониторинга TCP-соединений и пересылки запросов обработчику.
func (srv *Server) ListenAndServeTLS(certFile, keyFile string) error // Поддержка httpsСлужить
func (srv *Server) Shutdown(ctx context.Context) error // Добейтесь корректного закрытия соединений.
Создайте веб-сервис на основе приведенной выше структуры сервера:
package main
import (
"fmt"
"net/http"
)
type MyHandler2 struct{}
func (this *MyHandler2) ServeHTTP(w http.ResponseWriter, r *http.Request) {
fmt.Fprintln(w, «Маленький принц»)
}
func main() {
myHandler := MyHandler2{}
//Примечание: здесь нет функции HanlderFunc. Ее необходимо указать при определении сервера.
server := http.Server{
Addr: ":9090",
Handler: &myHandler,
}
server.ListenAndServe()
}
Происхождение веб-сервисов также происходит из одной точки, а именно из структуры Сервера.
srv := http.Server{
Addr: ":9090",
Здесь инициализируется служба сервера. Помимо отображения указанного порта прослушивания, существует также важный параметр обработчика по умолчанию, а именно http.DefaultServeMux, который обеспечивает функцию разрешения маршрута веб-службы. Прямо сейчас
Здесь инициализируется служба сервера. Помимо отображения указанного порта прослушивания, существует также важный параметр обработчика по умолчанию, а именно http.DefaultServeMux, который обеспечивает функцию разрешения маршрута веб-службы. Прямо сейчас
http.HandleFunc("/", helloWorldHandler)
Приведенный выше код фактически эквивалентен следующему:
handler := http.DefaultServeMux
handler.HandleFunc("/", helloWorldHandler)
srv := http.Server{
Addr: ":9090",
Handler: handler,
}
Мультиплексор http поддерживает таблицу сопоставления для разрешения маршрутов. При запуске службы все маршруты запросов будут анализироваться в этой таблице сопоставления. Ее структура:
type ServeMux struct {
mu sync.RWMutex
m map[string]muxEntry
es []muxEntry // slice of entries sorted from longest to shortest.
hosts bool // whether any patterns contain hostnames
}
type muxEntry struct {
h Handler
pattern string
}
Путь маршрута и соответствующий обработчик метода обработки хранятся в muxEntry. На основе этого интерфейса Mux также можно реализовать более сложные протоколы маршрутизации.
er := srv.ListenAndServe()
С помощью приведенного выше простого кода реализуется мониторинг и обслуживание сервиса. Так как же он это делает? С сомнениями я еще раз вошел в море кодов, чтобы найти код.
func (srv *Server) ListenAndServe() error {
if srv.shuttingDown() {
return ErrServerClosed
}
addr := srv.Addr
if addr == "" {
addr = ":http"
}
ln, err := net.Listen("tcp", addr)
if err != nil {
return err
}
return srv.Serve(ln)
}
func (srv *Server) Serve(l net.Listener) error {
if fn := testHookServerServe; fn != nil {
fn(srv, l) // call hook with unwrapped listener
}
origListener := l
l = &onceCloseListener{Listener: l}
defer l.Close()
if err := srv.setupHTTP2_Serve(); err != nil {
return err
}
if !srv.trackListener(&l, true) {
return ErrServerClosed
}
defer srv.trackListener(&l, false)
baseCtx := context.Background()
if srv.BaseContext != nil {
baseCtx = srv.BaseContext(origListener)
if baseCtx == nil {
panic("BaseContext returned a nil context")
}
}
var tempDelay time.Duration // how long to sleep on accept failure
ctx := context.WithValue(baseCtx, ServerContextKey, srv)
for {
rw, err := l.Accept()
if err != nil {
select {
case <-srv.getDoneChan():
return ErrServerClosed
default:
}
if ne, ok := err.(net.Error); ok && ne.Temporary() {
if tempDelay == 0 {
tempDelay = 5 * time.Millisecond
} else {
tempDelay *= 2
}
if max := 1 * time.Second; tempDelay > max {
tempDelay = max
}
srv.logf("http: Accept error: %v; retrying in %v", err, tempDelay)
time.Sleep(tempDelay)
continue
}
return err
}
connCtx := ctx
if cc := srv.ConnContext; cc != nil {
connCtx = cc(connCtx, rw)
if connCtx == nil {
panic("ConnContext returned nil")
}
}
tempDelay = 0
c := srv.newConn(rw)
c.setState(c.rwc, StateNew) // before Serve can return
go c.serve(connCtx)
}
}
Видно, что Golang получает веб-страницу по протоколу TCP, а затем вызывает метод Serve для обработки запроса на соединение. Метод Serve запускает горутину для асинхронной обработки, что также является основой высокого параллелизма.
В методе обслуживания клиентский запрос принимается и обрабатывается в бесконечном цикле (for). Основная логика следующая:
if tlsConn, ok := c.rwc.(*tls.Conn); ok {
if d := c.server.ReadTimeout; d != 0 {
c.rwc.SetReadDeadline(time.Now().Add(d))
}
if d := c.server.WriteTimeout; d != 0 {
c.rwc.SetWriteDeadline(time.Now().Add(d))
}
if err := tlsConn.Handshake(); err != nil {
// If the handshake failed due to the client not speaking
// TLS, assume they're speaking plaintext HTTP and write a
// 400 response on the TLS conn's underlying net.Conn.
if re, ok := err.(tls.RecordHeaderError); ok && re.Conn != nil && tlsRecordHeaderLooksLikeHTTP(re.RecordHeader) {
io.WriteString(re.Conn, "HTTP/1.0 400 Bad Request\r\n\r\nClient sent an HTTP request to an HTTPS server.\n")
re.Conn.Close()
return
}
c.server.logf("http: TLS handshake error from %s: %v", c.rwc.RemoteAddr(), err)
return
}
c.tlsState = new(tls.ConnectionState)
*c.tlsState = tlsConn.ConnectionState()
if proto := c.tlsState.NegotiatedProtocol; validNextProto(proto) {
if fn := c.server.TLSNextProto[proto]; fn != nil {
h := initALPNRequest{ctx, tlsConn, serverHandler{c.server}}
fn(c.server, tlsConn, h)
}
return
}
}
...
serverHandler{c.server}.ServeHTTP(w, w.req)
Среди них реализация ServeHTTP:
func (sh serverHandler) ServeHTTP(rw ResponseWriter, req *Request) {
handler := sh.srv.Handler
if handler == nil {
handler = DefaultServeMux
}
if req.RequestURI == "*" && req.Method == "OPTIONS" {
handler = globalOptionsHandler{}
}
handler.ServeHTTP(rw, req)
}
Здесь мы наконец находим метод-обработчик для обработки маршрутизации, который мы определили.
Весь процесс показан на рисунке:
Просматривая приведенный выше исходный код, мы можем в основном понять общий процесс обработки веб-запроса в golang.
Запрос — это инкапсулированный клиентский запрос, включающий всю информацию, такую как URL, метод, заголовок и т. д., а также некоторые удобные методы:
Любая информация, которую обработчик должен знать о запросе, должна быть получена из этого объекта. Как правило, этот объект не будет изменен напрямую.
type Request struct {
// Method specifies the HTTP method (GET, POST, PUT, etc.).For client requests an empty string means GET.
Method string
// URL specifies either the URI being requested (for server requests) or the URL to access (for client requests).
URL *url.URL
// The protocol version for incoming requests.
// Client requests always use HTTP/1.1.
Proto string // "HTTP/1.1"
ProtoMajor int // 1
ProtoMinor int // 1
// A header maps request lines to their values.
// If the header says
//
// accept-encoding: gzip, deflate
// Accept-Language: en-us
// Connection: keep-alive
//
// then
//
// Header = map[string][]string{
// "Accept-Encoding": {"gzip, deflate"},
// "Accept-Language": {"en-us"},
// "Connection": {"keep-alive"},
// }
Header Header
// Body is the request's body.
Body io.ReadCloser
ContentLength int64
TransferEncoding []string
Close bool
Host string
Form url.Values
PostForm url.Values
MultipartForm *multipart.Form
...
RemoteAddr string
...
}
ResponseWriter — это интерфейс, определяющий три метода:
Header(): возвращает объект Header. Вы можете установить заголовок с помощью метода Set(). Обратите внимание, что окончательная возвращаемая информация заголовка может не совпадать с той, которую вы написали, поскольку последующая обработка также может изменить значение объекта. заголовок (например, Set Content-Length, Content-type и другие операции) Write(): напишите основную часть ответа, например, здесь будет размещен контент в формате html или json. WriteHeader(): установка кода состояния. Если эта функция не вызывается, значением по умолчанию является http.StatusOK, то есть код состояния 211.
// A ResponseWriter interface is used by an HTTP handler to
// construct an HTTP response.
type ResponseWriter interface {
Header() Header
Write([]byte) (int, error)
WriteHeader(int)
}
websocketЗависит отhttpобновление Приходить,Сначала отправьте HTTP-запрос с заголовком запроса на обновление.,Поэтому нам нужно разобраться сHttpПерехватить запрос при запросе и определить, является ли онwebsocketобновлениепросить,Если да, то позвонитеgorilla/websocket
Обработка соответствующей функции библиотекиобновлениепросить。
Веб-сокету, реализованному официальной стандартной библиотекой Golang, несколько недостает функциональности. Представленная на этот раз библиотека gorilla/websocket представляет собой быструю, высококачественную и широко используемую библиотеку веб-сокетов, созданную Gorilla, которая компенсирует функциональные недостатки стандартной библиотеки. . не хватает. Кроме того, набор инструментов Gorilla Web содержит несколько практических библиотек инструментов, связанных с HTTP-приложениями. Если вам интересно, вы можете перейти на официальный сайт https://www.gorillatoolkit.org, чтобы получить его.
Библиотека gorilla/websocket представляет собой реализацию протокола websocket, определенного в RFC 6455. С точки зрения отправки и получения данных она предоставляет два типа API детального чтения и записи сообщений: сообщения данных и управляющие сообщения с точки зрения производительности; связанные параметры конфигурации для буферов и сжатия с точки зрения безопасности, вы можете использовать CheckOrigin, чтобы контролировать, поддерживается ли междоменная поддержка.
go get github.com/gorilla/websocket
package main
import (
"fmt"
"github.com/gorilla/websocket"
"log"
"net/http"
)
var upgrader = websocket.Upgrader{
ReadBufferSize: 4196,
WriteBufferSize: 1124,
CheckOrigin: func(r *http.Request) bool {
//if r.Method != "GET" {
// fmt.Println("method is not GET")
// return false
//}
//if r.URL.Path != "/ws" {
// fmt.Println("path error")
// return false
//}
return true
},
}
// ServerHTTP для обновления протоколов
func ServerHTTP(w http.ResponseWriter, r *http.Request) {
// Обновите протокол после получения http-запроса.
conn, err := upgrader.Upgrade(w, r, nil)
if err != nil {
log.Println("Error during connection upgrade:", err)
return
}
defer conn.Close()
for {
// Сторона Служить читает запрос клиента
messageType, message, err := conn.ReadMessage()
if err != nil {
log.Println("Error during message reading:", err)
break
}
log.Printf("Received:%s", message)
// Включение и выключение мониторинга соединения
conn.SetCloseHandler(func(code int, text string) error {
fmt.Println(code, text) // код и текст будут напечатаны при отключении
return nil
})
//Конец Служить возвращает запрос клиенту
err = conn.WriteMessage(messageType, message)
if err != nil {
log.Println("Error during message writing:", err)
return
}
}
}
func home(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Index Page")
}
func main() {
http.HandleFunc("/socket", ServerHTTP)
http.HandleFunc("/", home)
log.Fatal(http.ListenAndServe("localhost:8181", nil))
}
Upgrader
Отправлено сUpgradeпроситьголоваHttpпросить,Пучок http Запрос на переход на длинное соединение WebSocket
,Структура следующая:
type Upgrader struct {
// обновление websocket Тайм-аут завершения рукопожатия
HandshakeTimeout time.Duration
// io Размер кэша операции будет выделен автоматически, если не указан.
ReadBufferSize, WriteBufferSize int
// Писать пул кэша для операций с данными, если значение не задано, напишите buffers Будет выделено жизненному циклу ссылки.
WriteBufferPool BufferPool
//Укажите по порядку протокол, поддерживаемый Служить. Если значение существует, Служить будет соответствовать протоколу клиента, начиная с первого.
Subprotocols []string
// http функция реагирования на ошибку, если не установлена Error Затем он будет генерировать http.Error ответ об ошибке.
Error func(w http.ResponseWriter, r *http.Request, status int, reason error)
// CheckOrigin вернет true, если заголовок Origin запроса приемлем. Если CheckOrigin равен нулю, используется безопасное значение по умолчанию: если заголовок запроса Origin присутствует и хост-источник не равен заголовку хоста запроса, возвращается false.
// Функция проверки запросов для унифицированной проверки ссылок для предотвращения подделки межсайтовых запросов. Если флажок не установлен, установите функцию с возвращаемым значением true.
CheckOrigin func(r *http.Request) bool
// EnableCompression Указывает, должен ли сервер Служить пытаться согласовать сжатие каждой почты (RFC 7692)。 Установка для этого значения значения true не гарантирует поддержку сжатия. В настоящее время поддерживается только режим «бесконтекстного поглощения».
EnableCompression bool
}
Пример создания экземпляра Upgrader для запроса на обновление:
var upgrader = websocket.Upgrader{
ReadBufferSize: 1124, //Указываем размер кэша чтения
WriteBufferSize: 1124, //Указываем размер кэша Писать
CheckOrigin: checkOrigin,
}
// Определить источник запроса
func checkOrigin(r *http.Request) bool {
if r.Method != "GET" {
fmt.Println("method is not GET")
return false
}
if r.URL.Path != "/ws" {
fmt.Println("path error")
return false
}
return true
}
вCheckOringin
это функция,Эта функция используется дляперехватыватьиливыпускать Междоменный доменпросить。Возвращаемое значение функцииbool
тип,Прямо сейчасtrue
выпускать,false
перехватывать。еслипросить不是Междоменный доменпросить Никакое значение не может быть присвоено。
func (u *Upgrader) Upgrade(w http.ResponseWriter, r *http.Request, responseHeader http.Header) (*Conn, error)
Перейдите на соединение через веб-сокет и получите экземпляр conn. Все последующие операции отправки и получения имеют соединение, а его тип — websocket.Conn.
WriteMessage
первый Отправьте сообщение клиенту, используяWriteMessage(messageType int, data []byte)
,Параметр 1 — тип сообщения, параметр 2 — содержание сообщения:
func (e *Engine) ServeHTTP(w http.ResponseWriter, r *http.Request) {
//суждениепросить Этоwebsocketобновлениепросить。
if websocket.IsWebSocketUpgrade(r) {
conn, err := upgrader.Upgrade(w, r, w.Header())
conn.WriteMessage(websocket.TextMessage, []byte("hgs"))
} else {
//Обработка обычных запросов
c := newContext(w, r)
e.router.handle(c)
}
}
Или используйте метод func (c *Conn) NextWriter(messageType int) (io.WriteCloser, error) для получения средства записи, а затем вызовите func (w *messageWriter) Write(p []byte) (int, error) для записи данные.
ReadMessage()
Принимайте сообщения клиентов, используяReadMessage()
Эта операция заблокирует поток, поэтому рекомендуется запускать ее на других сопрограммах.。Эта функция имеет три возвращаемых значения:,получать сообщениятип、Получить содержимое сообщения, произошла ошибка. Разумеется, ошибка при обычном выполнении есть. ноль. После закрытия соединения тип возвращаемого значения -1 можно использовать для завершения операции чтения.
Пример:
func (e *Engine) ServeHTTP(w http.ResponseWriter, r *http.Request) {
//суждениепросить Этоwebsocketобновлениепросить。
if websocket.IsWebSocketUpgrade(r) {
conn, err := upgrader.Upgrade(w, r, w.Header())
conn.WriteMessage(websocket.TextMessage, []byte("wxm.alming"))
go func() {
for {
t, c, _ := conn.ReadMessage()
fmt.Println(t, string(c))
if t == -1 {
return
}
}
}()
} else {
//Обработка обычных запросов
c := newContext(w, r)
e.router.handle(c)
}
}
При этом вы можете отключить мониторинг подключения в настройках подключения.,ФункцияSetCloseHandler(h func(code int, text string) error)
Функция получает Функцияпараметр,Существует реализация по умолчанию, когда параметр равен нулю.,Его исходный код:
func (c *Conn) SetCloseHandler(h func(code int, text string) error) {
if h == nil {
h = func(code int, text string) error {
message := FormatCloseMessage(code, "")
c.WriteControl(CloseMessage, message, time.Now().Add(writeWait))
return nil
}
}
c.handleClose = h
}
Вы можете видеть, что параметрами функции являются типы int и string, которые точно такие же, как и во внешнем интерфейсе close(long строка) соответствует внешнему вызову close(long string)После закрытия соединения два параметра будут отправлены на серверную часть и, в конечном итоге,func(code int, text string) error
использовал。
//Http-вход
func (e *Engine) ServeHTTP(w http.ResponseWriter, r *http.Request) {
//суждениепросить Этоwebsocketобновлениепросить。
if websocket.IsWebSocketUpgrade(r) {
// получать http проситьназадобновлениепротокол
conn, err := upgrader.Upgrade(w, r, w.Header())
conn.SetCloseHandler(func(code int, text string) error {
fmt.Println(code, text)
return nil
})
// Отправьте сообщение клиенту, используя WriteMessage(messageType int, data []байт), параметр 1 — тип сообщения, параметр 2 — содержимое сообщения
conn.WriteMessage(websocket.TextMessage, []byte("обновлениеуспех"))
// Принимайте сообщения клиентов, используя ReadMessage(), эта операция блокирует поток, поэтому рекомендуется запускать ее на других сопрограммах.
//Возвращаемое значение (тип полученного сообщения, содержимое полученного сообщения, произошла ошибка) Конечно, ошибка при обычном выполнении ноль. После закрытия соединения тип возвращаемого значения -1 можно использовать для завершения операции чтения.
go func() {
for {
t, c, _ := conn.ReadMessage()
fmt.Println(t, string(c))
if t == -1 {
return
}
}
}()
} else {
//Обработка обычных запросов
c := newContext(w, r)
e.router.handle(c)
}
}
Код и текст будут напечатаны при отключении
Уведомление:Чтобы обработка отключения вступила в силу, должно бытьReadMessage()
В противном случае операция обработки отключения не будет запущена.。
Когда вы видите так много сред разработки, вы, возможно, какое-то время не знаете, какой выбрать. Xiaomu в основном рекомендует три платформы: Beego, Gin и Iris~
Особенности фреймворка:
Beego — это фреймворк в стиле RESTful с моделью MVC. Он поддерживает горячую компиляцию кода, автоматическое тестирование, автоматическую упаковку и развертывание, а также быструю разработку проектов, что делает разработку быстрее и проще.
Beego не только поддерживает интеллектуальную маршрутизацию, но также решает проблему, связанную с тем, что платформа Mux не поддерживает параметры маршрутизации. Кроме того, Beego также может выполнять интеллектуальный мониторинг количества запросов в секунду, потребления памяти, использования ЦП и состояния работы горутины, что позволяет разработчикам, а также персоналу по эксплуатации и техническому обслуживанию легче отслеживать текущий статус онлайн-проектов.
Beego имеет встроенные восемь модулей: сеанс, работа с кэшем, ведение журнала, анализ конфигурации, мониторинг производительности, работа с контекстом, ORM и моделирование запросов, что делает разработку более удобной.
Поскольку Beego использует встроенный HTTP-пакет языка Go для обработки сетевых запросов, Beego может полностью использовать функции поддержки параллелизма языка Go. В настоящее время существует множество продуктов с высоким уровнем параллелизма, разработанных с использованием платформы Beego.
Причины рекомендации:
Beego — это простая и удобная в использовании среда разработки приложений Go корпоративного уровня, разработанная экспертом по разработке языка Go «Asta Xie». У нее есть официальный веб-сайт и учебные пособия на китайском языке. В отличие от других языков платформы, Beego предоставляет не только графические руководства. Также предоставляются видеоуроки, что очень удобно для отечественных разработчиков.
Особенности фреймворка:
Gin разработан на основе идей Martini, первой среды веб-разработки для языка Go. Он использует модуль httprouter для увеличения скорости почти в 40 раз.
Фреймворк Gin имеет множество встроенных промежуточных программ, таких как Logger, Gzip, Authorization и т. д. В то же время, если вы хотите расширить промежуточное программное обеспечение, Gin также очень удобен.
Gin имеет встроенные средства проверки данных, а также поддерживает определяемые пользователем средства проверки данных.
Gin может собирать информацию об ошибках во время работы программы и фиксировать сбои программы, вызванные паникой, тем самым гарантируя, что наши веб-приложения всегда работают нормально.
Gin поддерживает стандартный формат данных формы, формат данных JSON, формат данных XML и формат данных YAML.
По умолчанию Gin поддерживает два метода привязки модели для привязки данных запроса к типам, а именно метод Must Bind и метод Must Bind.
Причины рекомендации:
Веб-фреймворк Http, полностью написанный на языке Go, обеспечивающий более быструю и высокопроизводительную среду веб-разработки на языке Go.
Особенности фреймворка:
По этому поводу есть поговорка: Iris — самый быстрый фреймворк для веб-разработки на Go. Что касается конкретной скорости, мы можем зайти на официальный сайт, чтобы увидеть результаты тестов, или самостоятельно загрузить код фреймворка и запустить тест производительности, чтобы увидеть результаты.
Iris называется версией Javascript/Node.js на языке Go. Он имеет очень простой API, облегчающий начало работы разработчиков.
Iris имеет множество встроенных промежуточных программ, а также поддерживает пользовательские промежуточные программы, такие как ведение журналов, управление разрешениями, междоменные запросы и т. д.
Платформа Iris может настраивать соответствующие функции обработки для любого HTTP-запроса.
Iris поддерживает несколько форматов данных, таких как уценка, xml, Json и Jsonp, для рендеринга представления.
При разработке с использованием платформы Iris новый контент будет автоматически компилироваться и загружаться при изменении исходного кода.
Причины рекомендации:
Если вы выбираете среду веб-разработки на языке Go с хорошей производительностью, легкостью и простотой в использовании, Iris — хороший выбор.
В конце концов, вы можете протестировать и узнать, какой фреймворк вы выберете.
Фреймворки — это инструменты для нашего развития. Только когда эти инструменты удобны, мы можем по-настоящему повысить эффективность нашей разработки.