ghttp.Server增加对多端口监听特性(HTTP/HTTPS),支持同一Server同时监听多端口的HTTP/HTTPS服务

This commit is contained in:
John
2018-04-27 22:12:11 +08:00
parent 67f9c5efb1
commit 98ff7cae15
6 changed files with 122 additions and 36 deletions

View File

@ -18,6 +18,7 @@ import (
"gitee.com/johng/gf/g/container/gmap"
"gitee.com/johng/gf/g/container/gtype"
"gitee.com/johng/gf/g/container/gqueue"
"time"
)
const (
@ -38,7 +39,6 @@ type Server struct {
hmcmu sync.RWMutex // handlerCache互斥锁
hhcmu sync.RWMutex // hooksCache互斥锁
name string // 服务名称,方便识别
server http.Server // 底层http server对象
config ServerConfig // 配置对象
status int8 // 当前服务器状态(0未启动1运行中)
methodsMap map[string]bool // 所有支持的HTTP Method(初始化时自动填充)
@ -60,6 +60,7 @@ type Server struct {
accessLogger *glog.Logger // access log日志对象
errorLogger *glog.Logger // error log日志对象
logHandler *gtype.Interface // 自定义的日志处理回调方法
serverCount *gtype.Int // 底层的Web Server数量
}
// 域名、URI与回调函数的绑定记录表
@ -118,6 +119,7 @@ func GetServer(name...interface{}) (*Server) {
accessLogger : glog.New(),
errorLogger : glog.New(),
logHandler : gtype.NewInterface(),
serverCount : gtype.NewInt(),
}
s.errorLogger.SetBacktraceSkip(4)
s.accessLogger.SetBacktraceSkip(4)
@ -138,38 +140,71 @@ func (s *Server) Run() error {
return errors.New("server is already running")
}
// 底层http server配置
if s.config.Handler == nil {
s.config.Handler = http.HandlerFunc(s.defaultHttpHandle)
}
// 底层http server初始化
s.server = http.Server {
Addr : s.config.Addr,
// 开启异步处理队列处理循环
s.startCloseQueueLoop()
// 开始执行底层Web Server创建端口监听
if len(s.config.HTTPSCertPath) > 0 && len(s.config.HTTPSKeyPath) > 0 {
// HTTPS
if len(s.config.HTTPSAddr) == 0 {
if len(s.config.Addr) > 0 {
s.config.HTTPSAddr = s.config.Addr
} else {
s.config.HTTPSAddr = gDEFAULT_HTTPS_ADDR
}
}
array := strings.Split(s.config.HTTPSAddr, ",")
for _, addr := range array {
s.servedCount.Add(1)
go func() {
if err := s.newServer(addr).ListenAndServeTLS(s.config.HTTPSCertPath, s.config.HTTPSKeyPath); err != nil {
glog.Error(err)
s.servedCount.Add(-1)
}
}()
}
}
// HTTP
if s.servedCount.Val() == 0 && len(s.config.Addr) == 0 {
s.config.Addr = gDEFAULT_HTTP_ADDR
}
array := strings.Split(s.config.Addr, ",")
for _, addr := range array {
s.servedCount.Add(1)
go func() {
if err := s.newServer(addr).ListenAndServe(); err != nil {
glog.Error(err)
s.servedCount.Add(-1)
}
}()
}
s.status = 1
// 阻塞执行直到所有Web Server退出
for s.servedCount.Val() > 0 {
time.Sleep(time.Second)
}
return nil
}
// 生成一个底层的Web Server对象
func (s *Server) newServer(addr string) *http.Server {
return &http.Server {
Addr : addr,
Handler : s.config.Handler,
ReadTimeout : s.config.ReadTimeout,
WriteTimeout : s.config.WriteTimeout,
IdleTimeout : s.config.IdleTimeout,
MaxHeaderBytes : s.config.MaxHeaderBytes,
}
// 开启异步处理队列处理循环
s.startCloseQueueLoop()
// 执行端口监听
if len(s.config.HTTPSCertPath) > 0 && len(s.config.HTTPSKeyPath) > 0 {
// HTTPS
if err := s.server.ListenAndServeTLS(s.config.HTTPSCertPath, s.config.HTTPSKeyPath); err != nil {
glog.Error(err)
return err
}
} else {
// HTTP
if err := s.server.ListenAndServe(); err != nil {
glog.Error(err)
return err
}
}
s.status = 1
return nil
}
// 清空当前的handlerCache

View File

@ -12,18 +12,23 @@ import (
"net/http"
)
const (
gDEFAULT_HTTP_ADDR = ":80" // 默认HTTP监听地址
gDEFAULT_HTTPS_ADDR = ":443" // 默认HTTPS监听地址
)
// HTTP Server 设置结构体
type ServerConfig struct {
// HTTP Server基础字段
Addr string // 监听IP和端口监听本地所有IP使用":端口"
Handler http.Handler // 默认的处理函数
Addr string // 监听IP和端口监听本地所有IP使用":端口"(支持多个地址,使用","号分隔)
HTTPSAddr string // HTTPS服务监听地址(支持多个地址,使用","号分隔)
HTTPSCertPath string // HTTPS证书文件路径
HTTPSKeyPath string // HTTPS签名文件路径
Handler http.Handler // 默认的处理函数
ReadTimeout time.Duration
WriteTimeout time.Duration
IdleTimeout time.Duration
MaxHeaderBytes int // 最大的header长度
// gf 扩展信息字段
IndexFiles []string // 默认访问的文件列表
IndexFolder bool // 如果访问目录是否显示目录列表
ServerAgent string // server agent
@ -32,7 +37,8 @@ type ServerConfig struct {
// 默认HTTP Server
var defaultServerConfig = ServerConfig {
Addr : ":80",
Addr : "",
HTTPSAddr : "",
Handler : nil,
ReadTimeout : 60 * time.Second,
WriteTimeout : 60 * time.Second,

View File

@ -50,11 +50,39 @@ func (s *Server)SetAddr(addr string) error {
}
// 设置http server参数 - Port
func (s *Server)SetPort(port int) error {
func (s *Server)SetPort(port...int) error {
if s.status == 1 {
return errors.New("server config cannot be changed while running")
}
s.config.Addr = ":" + strconv.Itoa(port)
if len(port) > 0 {
s.config.Addr = ""
for _, v := range port {
s.config.Addr += ":" + strconv.Itoa(v)
}
}
return nil
}
// 设置http server参数 - HTTPS Addr
func (s *Server)SetHTTPSAddr(addr string) error {
if s.status == 1 {
return errors.New("server config cannot be changed while running")
}
s.config.HTTPSAddr = addr
return nil
}
// 设置http server参数 - HTTPS Port
func (s *Server)SetHTTPSPort(port...int) error {
if s.status == 1 {
return errors.New("server config cannot be changed while running")
}
if len(port) > 0 {
s.config.HTTPSAddr = ""
for _, v := range port {
s.config.HTTPSAddr += ":" + strconv.Itoa(v)
}
}
return nil
}

View File

@ -465,7 +465,9 @@ func instance() {
func main() {
r, e := db.Table("user").Where("name like ?", "%john%").Select()
fmt.Println(e)
fmt.Println(r)
//create()
//create()
//insert()
@ -479,7 +481,7 @@ func main() {
//linkopSelect1()
//linkopSelect2()
//linkopSelect3()
linkopCount1()
//linkopCount1()
//linkopUpdate1()
//linkopUpdate2()
//linkopUpdate3()

View File

@ -0,0 +1,16 @@
package main
import (
"gitee.com/johng/gf/g/net/ghttp"
)
func main() {
s := ghttp.GetServer()
s.BindHandler("/", func(r *ghttp.Request){
r.Response.Writeln("您可以同时通过HTTP和HTTPS方式看到该内容")
})
s.EnableHTTPS("/home/john/temp/server.crt", "/home/john/temp/server.key")
s.SetHTTPSPort(443)
s.SetPort(80)
s.Run()
}

View File

@ -1,12 +1,11 @@
package main
import (
"gitee.com/johng/gf/g/util/gconv"
"math"
"fmt"
"math/rand"
)
func main() {
for i := 0; i < 100; i++ {
fmt.Println(rand.Intn(200))
}
fmt.Println(gconv.String(uint(math.MaxUint64)))
}