mirror of
https://gitee.com/johng/gf
synced 2026-06-06 16:21:40 +08:00
ghttp.Server增加对多端口监听特性(HTTP/HTTPS),支持同一Server同时监听多端口的HTTP/HTTPS服务
This commit is contained in:
@ -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
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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
|
||||
}
|
||||
|
||||
|
||||
@ -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()
|
||||
|
||||
16
geg/net/ghttp/https/https_http.go
Normal file
16
geg/net/ghttp/https/https_http.go
Normal 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()
|
||||
}
|
||||
@ -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)))
|
||||
}
|
||||
Reference in New Issue
Block a user