GoWeb web服务器的创建

简介

go提供了一系列用于创建web服务器的标准库,而且通过go创建一个服务器的步骤非常简单,只要通过 net/http包调用 ListenAndServe函数并传入网络地址以及负责处理请求的处理器(handler)作为参数就可以了。如果网络地址参数为空字符串,那么服务器默认使用80端口进行网络连接;如果处理器参数为nil, 那么服务器将使用默认的多路复用器DefaultServeMux,当然,也可以通过调用NewServeMux函数创建一个多路复用器。多路复用器接收到用户的请求之后根据请求的URL来判断使用哪个处理器来处理请求,找到后就会重定向到对应的处理器来处理请求

默认的多路复用器(DefaultServeMux)

  1. 使用处理器函数处理请求
package main

import (
	"fmt"
	"net/http"
)
//创建处理器函数
func handler(w http.ResponseWriter, r *http.Request)  {
	fmt.Fprintln(w, "正在通过处理器函数处理你的请求")
}
func main() {
	http.HandleFunc("/", handler)
	//创建路由
	http.ListenAndServe(":8080", nil)
}
  • func HandleFunc
func HandleFunc(pattern string, handler func(ResponseWriter, *Request))

HandleFunc注册一个处理器函数handler和对应的模式pattern(注册到DefaultServeMux)。ServeMux的文档解释了模式的匹配机制

处理器函数的实现原理

  • go语言拥有一种HandlerFunc函数类型,它可以将一个带有正确签名的函数 f 转换成一个带有方法 f 的Handler

type HandlerFunc

type HandlerFunc func(ResponseWriter, *Request)

HandlerFunc type是一个适配器,通过类型转换让我们可以将普通的函数作为HTTP处理器使用。如果f是一个具有适当签名的函数,HandlerFunc(f)通过调用f实现了Handler接口

  1. 使用处理器处理请求
package main

import (
	"fmt"
	"net/http"
)

type MyHandler struct {

}

func (m *MyHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	fmt.Fprintln(w, "通过自己创建的处理器处理请求!")
}
func main() {
	myHandler := MyHandler{}
	http.Handle("/myHandler", &myHandler)
	http.ListenAndServe(":8080", nil)
}

浏览器访问
http://127.0.0.1:8080/myHandler

  • func Handle
func Handle(pattern string, handler Handler)

Handle注册HTTP处理器handler和对应的模式pattern(注册到DefaultServeMux)。如果该模式已经注册有一个处理器,Handle会panic。ServeMux的文档解释了模式的匹配机制

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

实现了Handler接口的对象可以注册到HTTP服务端,为特定的路径及其子树提供服务

ServeHTTP应该将回复的头域和数据写入ResponseWriter接口然后返回。返回标志着该请求已经结束,HTTP服务端可以转移向该连接上的下一个请求

只要某个结构体实现了 Handler接口中的 ServeHTTP方法,那么它就是一个处理器

  1. 通过Server结构对服务器进行更详细的配置
  • type Server
type Server struct {
    Addr           string        // 监听的TCP地址,如果为空字符串会使用":http"
    Handler        Handler       // 调用的处理器,如为nil会调用http.DefaultServeMux
    ReadTimeout    time.Duration // 请求的读取操作在超时前的最大持续时间
    WriteTimeout   time.Duration // 回复的写入操作在超时前的最大持续时间
    MaxHeaderBytes int           // 请求的头域最大长度,如为0则用DefaultMaxHeaderBytes
    TLSConfig      *tls.Config   // 可选的TLS配置,用于ListenAndServeTLS方法
    // TLSNextProto(可选地)指定一个函数来在一个NPN型协议升级出现时接管TLS连接的所有权。
    // 映射的键为商谈的协议名;映射的值为函数,该函数的Handler参数应处理HTTP请求,
    // 并且初始化Handler.ServeHTTP的*Request参数的TLS和RemoteAddr字段(如果未设置)。
    // 连接在函数返回时会自动关闭。
    TLSNextProto map[string]func(*Server, *tls.Conn, Handler)
    // ConnState字段指定一个可选的回调函数,该函数会在一个与客户端的连接改变状态时被调用。
    // 参见ConnState类型和相关常数获取细节。
    ConnState func(net.Conn, ConnState)
    // ErrorLog指定一个可选的日志记录器,用于记录接收连接时的错误和处理器不正常的行为。
    // 如果本字段为nil,日志会通过log包的标准日志记录器写入os.Stderr。
    ErrorLog *log.Logger
    // 内含隐藏或非导出字段
}

Server类型定义了运行HTTP服务端的参数。Server的零值是合法的配置

package main

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

type MyHandler struct {

}

func (m *MyHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	fmt.Fprintln(w, "通过详细配置服务器的信息来处理请求!")
}
func main() {
	myHandler := MyHandler{}
	//创建Server结构,并详细配置
	server := http.Server{
		Addr: ":8080",
		Handler: &myHandler,
		ReadTimeout: 2 * time.Second,
	}
	server.ListenAndServe()

}

使用自己创建的多路复用器

  1. 在创建服务器时,还可以通过 NewServeMux方法创建一个多路复用器

func NewServeMux

func NewServeMux() *ServeMux

NewServeMux创建并返回一个新的*ServeMux

package main

import (
	"fmt"
	"net/http"
)

func handler(w http.ResponseWriter, r *http.Request)  {
	fmt.Fprintln(w, "通过自己创建的多路复用器来处理请求")
}
func main() {
	mux := http.NewServeMux()
	mux.HandleFunc("/myMux", handler)
	http.ListenAndServe(":8080", mux)
}

结构体ServeMux

type ServeMux

type ServeMux struct {
    // 内含隐藏或非导出字段
}

ServeMux类型是HTTP请求的多路转接器。它会将每一个接收的请求的URL与一个注册模式的列表进行匹配,并调用和URL最匹配的模式的处理器。

模式是固定的、由根开始的路径,如"/favicon.ico",或由根开始的子树,如"/images/"(注意结尾的斜杠)。较长的模式优先于较短的模式,因此如果模式"/images/“和”/images/thumbnails/“都注册了处理器,后一个处理器会用于路径以”/images/thumbnails/“开始的请求,前一个处理器会接收到其余的路径在”/images/"子树下的请求。

注意,因为以斜杠结尾的模式代表一个由根开始的子树,模式"/“会匹配所有的未被其他注册的模式匹配的路径,而不仅仅是路径”/"。

模式也能(可选地)以主机名开始,表示只匹配该主机上的路径。指定主机的模式优先于一般的模式,因此一个注册了两个模式"/codesearch"和"codesearch.google.com/"的处理器不会接管目标为"http://www.google.com/"的请求。

ServeMux还会注意到请求的URL路径的无害化,将任何路径中包含".“或”…"元素的请求重定向到等价的没有这两种元素的URL。(参见path.Clean函数)

结构体ServeMux 相关方法

  • func (*ServeMux) Handle
func (mux *ServeMux) Handle(pattern string, handler Handler)

Handle注册HTTP处理器handler和对应的模式pattern。如果该模式已经注册有一个处理器,Handle会panic。

  • func (*ServeMux) HandleFunc
func (mux *ServeMux) HandleFunc(pattern string, handler func(ResponseWriter, *Request))

HandleFunc注册一个处理器函数handler和对应的模式pattern。

  • func (*ServeMux) Handler
func (mux *ServeMux) Handler(r *Request) (h Handler, pattern string)

Handler根据r.Method、r.Host和r.URL.Path等数据,返回将用于处理该请求的HTTP处理器。它总是返回一个非nil的处理器。如果路径不是它的规范格式,将返回内建的用于重定向到等价的规范路径的处理器。

Handler也会返回匹配该请求的的已注册模式;在内建重定向处理器的情况下,pattern会在重定向后进行匹配。如果没有已注册模式可以应用于该请求,本方法将返回一个内建的"404 page not found"处理器和一个空字符串模式。

  • func (*ServeMux) ServeHTTP
func (mux *ServeMux) ServeHTTP(w ResponseWriter, r *Request)

ServeHTTP将请求派遣到与请求的URL最匹配的模式对应的处理器

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

wuxingge

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值