返回介绍

上卷 程序设计

中卷 标准库

下卷 运行时

源码剖析

附录

server

发布于 2024-10-12 19:15:52 字数 2057 浏览 0 评论 0 收藏 0

基础服务器,负责客户端接入(HTTP/2, TLS)和请求。逻辑则由处理器(Handler)实现。

// http/server.go

type Server struct {
	// Addr optionally specifies the TCP address for the server to listen on,
	// in the form "host:port". If empty, ":http" (port 80) is used.
	Addr string

	Handler Handler // handler to invoke, http.DefaultServeMux if nil
}

源码剖析

标准库提供了简便函数,可用于测试。正式项目,应建议创建实例,并设置相关参数。
如果需要自行监听( REUSEPORT ),可改用 Serve 方法。

// http/server.go

func ListenAndServe(addr string, handler Handler) error {
	server := &Server{Addr: addr, Handler: handler}
	return server.ListenAndServe()
}
// http/server.go

func (srv *Server) ListenAndServe() error {
	addr := srv.Addr
	if addr == "" {
		addr = ":http"
	}
	ln, err := net.Listen("tcp", addr)
	return srv.Serve(ln)
}

先设置 HTTP/2,然后循环处理接入请求。
为每个客户端生成一个 goroutine,标准方式。

// http/server.go

func (srv *Server) Serve(l net.Listener) error {
	defer l.Close()

	if err := srv.setupHTTP2_Serve(); err != nil {
		return err
	}

	for {
		rw, err := l.Accept()
		c := srv.newConn(rw)
		go c.serve(connCtx)
	}
}

接下来,依次是 TLS、Request、Response,转入 Handler 处理。

// http/server.go

func (c *conn) serve(ctx context.Context) {
	defer func() {
        
        // 拦截恐慌,隔离在单一接入内。
		if err := recover(); err != nil && err != ErrAbortHandler {
            ...
		}
        
        // 关闭连接。(非劫持)
		if !c.hijacked() {
			c.close()
		}
        
	}()
    
    // TLS
	if tlsConn, ok := c.rwc.(*tls.Conn); ok {
        ...
	}

	// HTTP/1.x from here on.

	for {
        // 准备请求和返回对象。
		w, err := c.readRequest(ctx)

        // 处理器。
        serverHandler{c.server}.ServeHTTP(w, w.req)
        
        // 结束,清理相关资源。
		w.finishRequest()
	}
}

未提供自定义处理器时,使用默认路由。

// http/server.go

type serverHandler struct {
	srv *Server
}

func (sh serverHandler) ServeHTTP(rw ResponseWriter, req *Request) {
	handler := sh.srv.Handler
	if handler == nil {
		handler = DefaultServeMux
	}

	handler.ServeHTTP(rw, req)
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文