从零实现gin day01

前言

刚开始学go想着不能一直输入,得有点输出才能记得住学的东西,故决定写一些学习笔记来记录自己的学习历程.

知识点

  • 使用go开启TCP服务
  • 使用go发送http请求
  • 实现TCP监听回调服务

http请求封装

怎么用go开启TCP服务

go 复制代码
package main  
  
import (  
    "fmt"  
    "log"  
    "net/http"  
)  
  
func main() {  
    http.HandleFunc("/", func(writer http.ResponseWriter, request *http.Request) {  
    writer.Write([]byte(fmt.Sprintf("hello %s\n", "cc")))  
})  
  
    log.Fatal(http.ListenAndServe(":7999", nil))  
}

http.HandleFunc 添加一个路由,添加了路由我们怎么去监听这个路由是否正确呢?http.ListenAndServe中的第二个参数就派上用场了,从源码中可以看到,在开启TCP监听端口之后会回调一个handler requests这个Handler是一个接口,里面有一个ServeHTTP方法,所以只要实现了这个方法的都可以作为参数传给ListenAndServe

监听源码

go 复制代码
type Handler interface {  
    ServeHTTP(ResponseWriter, *Request)  
}
// ListenAndServe listens on the TCP network address addr and then calls  
// Serve with handler to handle requests on incoming connections.  
// Accepted connections are configured to enable TCP keep-alives.
// ListenAndServe always returns a non-nil error.  
func ListenAndServe(addr string, handler Handler) error {  
    server := &Server{Addr: addr, Handler: handler}  
    return server.ListenAndServe()  
}

实现

go 复制代码
package main  
  
import (  
    "fmt"  
    "net/http"  
)  
  
type Engine struct {  
}  
  
func (e *Engine) ServeHTTP(w http.ResponseWriter, r *http.Request) {  
    path := r.URL.Path  
    if path == "/" {  
        fmt.Fprint(w, "index")  
    } else if path == "/hello" {  
        fmt.Fprint(w, "hello world")  
    } else {  
        fmt.Fprint(w, "404")  
    }  
}

那么main函数中的ListenAndServe就可以直接使用这个作为回调方法传入.

go 复制代码
func main() {  
    http.HandleFunc("/", func(writer http.ResponseWriter, request *http.Request) {  
        writer.Write([]byte(fmt.Sprintf("hello %s\n", "cc")))  
    })   
    e := new(Engine)  
    log.Fatal(http.ListenAndServe(":7999", e))  
}

我们使用postman进行测试,都出现了我们预期的结果,但是在http.HandleFunc中写的匿名函数并没有执行,要想这个匿名函数执行就要把其放到ServeHTTP中去.所以我们可以进一步改造.

给Engine添加router,封装Post,Get,Run方法

go 复制代码
package main  
  
import (  
    "fmt"  
    "net/http"  
)  
  
type HandleFunc http.HandlerFunc  
  
type Engine struct {  
    router map[string]HandleFunc  
}  
  
func newEngine() *Engine {  
    return &Engine{router: make(map[string]HandleFunc)}  
}  
  
func (e *Engine) ServeHTTP(w http.ResponseWriter, r *http.Request) {  
    key := r.Method + "-" + r.URL.Path  
    if h, ok := e.router[key]; ok {  
        h(w, r)  
    } else {  
        w.WriteHeader(http.StatusNotFound)
        fmt.Fprint(w, "404")  
    }  
}  
func (e *Engine) AddRouter(method string, path string, handle HandleFunc) {  
    key := method + "-" + path  
    e.router[key] = handle  
}  
func (e *Engine) Post(path string, handle HandleFunc) {  
    e.AddRouter("POST", path, handle)  
}  
func (e *Engine) Get(path string, handle HandleFunc) {  
    e.AddRouter("GET", path, handle)  
}  
  
func (e *Engine) Run(addr string) (err error) {  
    return http.ListenAndServe(addr, e)  
}

我们给Engine添加了一个router变量,类型为map[string]HandleFunc这样就能通过key找到其对应的HandleFunc方法,从而执行.

总结

本章我们完成了TCP服务监听的封装,并能通过Post,Get添加路由请求,并且能对不存在的路由进行提示.

更多详情连接:geektutu.com/post/gee.ht...

相关推荐
有梦不弃5 小时前
模块化单体架构设计方案:DDD + 六边形架构落地实践
后端·架构
江南十四行10 小时前
Spring框架核心(上)——IoC控制反转与DI依赖注入详解
java·后端·spring
IT_陈寒10 小时前
Redis缓存击穿把我坑惨了,原来这样设过期时间才靠谱
前端·人工智能·后端
妙码生花11 小时前
从 PHP 到 AI + Golang,程序员自救转型手记(五十二):管理员权限检查中间件,AI 随意放行预闯大祸
前端·后端·go
创安电气研究所11 小时前
用 Node.js 将变频器运行数据接入 MQTT
后端
董员外11 小时前
RAG 系统进化论(八):Agentic RAG(智能体式 RAG),从回答问题到完成任务
人工智能·后端·设计模式
大勇前进12 小时前
告别 div 满天飞,HTML5 语义化标签真的有必要用吗?
后端
小满zs12 小时前
Go语言第六章(结构体)
后端·go
属于自己的天空12 小时前
每天省去重复 Prompt:我用 Skills 把 CRUD 生成标准化了
前端·后端