golang实现一个简易的http路由及其原理

  1. 前提:实现一个http路由必需要了解net/http包,主要是go/src/net/http/server.go文件
  2. go实现一个web路由主要作三件事:
    • 监听端口
    • 接收客户端的请求
    • 为每一个请求分配对应的handler(对应到php中就是将请求转发到相应的controller和action)

下面是一个简单的实现路由的逻辑php

package main

import (
        "fmt"
        "net/http"
)

func rootGateWay(w http.ResponseWriter, r *http.Request) {
        println("Welcome to Chris's homepage! ")
}

func defaultGateWay(w http.ResponseWriter, r *http.Request) {
        fmt.Fprintf(w, "Hello jingjing")
        println("Welcome to Chris's homepage! ")
}

func main() {
        http.HandleFunc("/", defaultGateWay)    
        http.ListenAndServe(":8080", nil)
}

//访问http://host:8080/ 便可看到Hello jingjin

 由上面这个例子可知,咱们只执行了两步就完成了一个简易的web路由,分别执行了HandleFunc以及ListenAndServe两个函数。那这两个函数中又分别执行了什么操做呢web

先看下面这段源码:网络

//用于响应http请求,返回数据
type Handler interface {
        ServeHTTP(ResponseWriter, *Request)                                                                                                                                                                                                                                   
}

//HandlerFunc类型实现了Handler接口
type HandlerFunc func(ResponseWriter, *Request)                                                                                                                                                                                                                               

// ServeHTTP calls f(w, r).
func (f HandlerFunc) ServeHTTP(w ResponseWriter, r *Request) {
        f(w, r)
}

//调用默认ServerMux的HandleFunc方法
func HandleFunc(pattern string, handler func(ResponseWriter, *Request)) {                                                                                                                 
        DefaultServeMux.HandleFunc(pattern, handler)
}
//把方法handler转换成HandlerFunc类型,即实现了Handler接口;再执行Handle方法
func (mux *ServeMux) HandleFunc(pattern string, handler func(ResponseWriter, *Request)) {
        mux.Handle(pattern, HandlerFunc(handler))
}

//路由器注册一个handler给指定的parttern
func (mux *ServeMux) Handle(pattern string, handler Handler) {
        ....
}

不难看出,执行HandleFunc其实就是为某一规则的请求注册处理器。并发

下面咱们看看ListenAndServe都干了什么,看下面一段源码:tcp

func ListenAndServe(addr string, handler Handler) error {
        //初始化一个Server Struct  赋值server的地址和Handler,不过Handler常常性为空,由于会使                          //用DefaultServeMux
        server := &Server{Addr: addr, Handler: handler}                                                                                                                                        
        return server.ListenAndServe()
}

//经过tcp网络监听addr地址 
func (srv *Server) ListenAndServe() error {
        addr := srv.Addr
        if addr == "" {                                                                                                                                                                        
                addr = ":http"
        }
        ln, err := net.Listen("tcp", addr)
        if err != nil {
                return err
        }
        //for死循环一直接受http request, 每一个请求开启一个新的goroutine处理
        return srv.Serve(tcpKeepAliveListener{ln.(*net.TCPListener)})
}

由此,咱们能够简单概括出上文代码所作的操做:函数

  • 为不一样的url规则注册路由handler  
  • 建立server并监听端口
  • for循环一直接收request并并发处理

 

PS:  这一期的仍是比较简单,下一期争取实现一个真正能知足业务需求的http路由和web url

相关文章
相关标签/搜索