为你自己学Go
  • README
  • PART01.Web框架概览
    • 1.01 Web框架概览:学习路线
    • 1.02 Web框架概览-Beego框架分析
    • 1.03 Web框架概览-GIN框架分析
    • 1.04 Web框架概览-Iris框架分析
    • 1.05 Web框架概览-Echo框架分析
  • PART02.Server
    • 2.01 Server详解与面试要点
  • PART03.路由树
    • 3.01 路由树-Beego&GIN&Echo实现与设计总结
    • 3.02 路由树-全静态匹配
    • 3.03 路由树-TDD起步
    • 3.04 路由树-静态匹配测试用例
    • 3.05 路由树-静态匹配之路由查找
    • 3.06 路由树-静态匹配之集成Server
    • 3.07 路由树-通配符匹配之路由注册
    • 3.08 路由树-通配符匹配之路由查找与测试
    • 3.09 路由树-参数路径之基本注册和查找
    • 3.10 路由树-参数路径之校验
    • 3.11 路由树-参数路径之参数值
    • 3.12 路由树-总结与面试要点
  • PART04.课后复习
    • 4.01 课后复习-Server
    • 4.02 课后复习-Route
  • PART05.Context
    • 5.01 Context-简介
    • 5.02 Context-Beego Context设计分析
    • 5.03 Context-Gin Context设计分析
    • 5.04 Context-Echo和Iris的Context设计分析
    • 5.05 Context-处理输入输出总结
    • 5.06 Context-处理输入之Body输入
    • 5.07 Context-处理输入之表单输入
    • 5.08 Context-处理输入之查询参数、路径参数和StringValue
    • 5.09 Context-处理输出
    • 5.10 Context-总结与面试要点
  • PART06.AOP
    • 6.01 AOP简介与不同框架设计概览
    • 6.02 AOP设计方案-Middleware
  • PART07.Middleware
    • 7.01 Middleware-AccessLog
    • 7.02 Middleware-Trace简介和OpenTelemetry
    • 7.03 Middleware-OpenTelemetry测试
    • 7.04 Middleware-OpenTelemetry总结
    • 7.05 Prometheus详解
    • 7.06 Middleware-Prometheus
    • 7.07 Middleware-错误页面
    • 7.08 Middleware-从panic中恢复
    • 7.09 Middleware总结和面试
  • PART08.Review
    • 8.01 课后复习-AOP
    • 8.02 课后复习-Context
    • 8.03 课后复习-Middleware-AccessLog
  • PART09.Appendix
    • 附录1.责任链模式
    • 附录2.生成器模式
    • 附录3.函数选项模式
  • xiaochengxu
    • 01.原力去水印
    • 02.KeePass密码管理:安全轻松的管理您的密码
Powered by GitBook
On this page
  • PART1. Server
  • 1.1 接口定义
  • 1.2 实现接口的Start()方法
  • 1.3 定义注册路由的方法addRoute()
  • PART2. 完成Server时的工程结构
  • 附录
  • 1. 可以魔改的点
  1. PART04.课后复习

4.01 课后复习-Server

本节课工程结构:

(base) yanglei@yuanhong v4-rc % tree ./
./

0 directories, 0 files

PART1. Server

1.1 接口定义

serverInterface.go:

package v4_rc

import "net/http"

// ServerInterface 服务器实体接口
// 用于定义服务器实体的行为
type ServerInterface interface {
	// Handler 组合http.Handler接口
	http.Handler
	// Start 启动服务器
	Start(addr string) error
}

这里组合http.Handler,是为了最终调用http.Serve(),使得该方法的第2个参数是我们自己实现的http.Handler接口的实现.这一点我当时整理笔记时其实是不理解的,我复习时也发现我解释不清楚这件事.故补充.

1.2 实现接口的Start()方法

1.2.1 实现Start()方法

server.go:

package v4_rc

import (
	"net"
	"net/http"
)

type Server struct {
}

// ServeHTTP 是http.Handler接口的方法 此处必须先写个实现 不然Server不是http.Handler接口的实现
func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	panic("implement me")
}

// Start 启动服务器
func (s *Server) Start(addr string) error {
	listener, err := net.Listen("tcp", addr)
	if err != nil {
		return err
	}

	return http.Serve(listener, s)
}

在net.Listen()和http.Serve()之间做框架的操作,例如生命周期回调.

1.2.2 测试

server_test.go:

package v4_rc

import (
	"testing"
)

// TestServer_Start 测试服务器启动
func TestServer_Start(t *testing.T) {
	s := &Server{}
	err := s.Start(":8081")
	if err != nil {
		t.Fatal(err)
	}
}

1.3 定义注册路由的方法addRoute()

1.3.1 定义Context

context.go:

package v4_rc

type Context struct {
}

这里其实是为了定义HandleFunc,而定义HandleFunc是为了定义AddRoute().

1.3.2 定义HandleFunc

handle_func.go

package v4_rc

type HandleFunc func(ctx *Context)

1.3.3 在接口上定义addRoute()

server_interface.go:

package v4_rc

import "net/http"

// ServerInterface 服务器实体接口
// 用于定义服务器实体的行为
type ServerInterface interface {
	// Handler 组合http.Handler接口
	http.Handler
	// Start 启动服务器
	Start(addr string) error

	// addRoute 注册路由
	addRoute(method string, pattern string, handler HandleFunc)
}

1.3.4 在实现上定义addRoute()

server.go:

package v4_rc

import (
	"net"
	"net/http"
)

type Server struct {
}

// ServeHTTP 是http.Handler接口的方法 此处必须先写个实现 不然Server不是http.Handler接口的实现
func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	panic("implement me")
}

// Start 启动服务器
func (s *Server) Start(addr string) error {
	listener, err := net.Listen("tcp", addr)
	if err != nil {
		return err
	}

	return http.Serve(listener, s)
}

// addRoute 注册路由
func (s *Server) addRoute(method string, pattern string, handler HandleFunc) {
	panic("implement me")
}

1.3.5 定义addRoute()的衍生方法

或者也可以说是暴露给使用者的方法

server.go:

package v4_rc

import (
	"net"
	"net/http"
)

type Server struct {
}

// ServeHTTP 是http.Handler接口的方法 此处必须先写个实现 不然Server不是http.Handler接口的实现
func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	panic("implement me")
}

// Start 启动服务器
func (s *Server) Start(addr string) error {
	listener, err := net.Listen("tcp", addr)
	if err != nil {
		return err
	}

	return http.Serve(listener, s)
}

// addRoute 注册路由
func (s *Server) addRoute(method string, pattern string, handler HandleFunc) {
	panic("implement me")
}

// GET 注册GET路由
func (s *Server) GET(path string, handler HandleFunc) {
	s.addRoute(http.MethodGet, path, handler)
}

// POST 注册POST路由
func (s *Server) POST(path string, handler HandleFunc) {
	s.addRoute(http.MethodPost, path, handler)
}

PART2. 完成Server时的工程结构

(base) yanglei@yuanhong v4-rc % tree ./
./
├── context.go
├── handle_func.go
├── server.go
├── server_interface.go
└── server_test.go

0 directories, 5 files

附录

1. 可以魔改的点

  • 将addr作为Server的一个成员属性

  • 我看原生的http.Server结构体为了支持HTTPS,组合了一个*tls.Config,可以尝试

Last updated 9 months ago