daShangDao_xy_dll/http/service/httpServer.go

95 lines
2.1 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package service
import (
"context"
"errors"
"fmt"
"log"
"net/http"
"sync"
"time"
)
// HTTPServer 封装HTTP服务器功能
type HTTPServer struct {
server *http.Server
wg sync.WaitGroup
}
// NewServer 创建一个新的HTTP服务器实例
func NewServer(addr string, handler http.Handler) *HTTPServer {
return &HTTPServer{
server: &http.Server{
Addr: addr,
Handler: handler,
},
}
}
// Start 启动HTTP服务器在协程中支持context
func (s *HTTPServer) Start(ctx context.Context) error {
log.Printf("HTTP服务器正在启动监听地址: %s", s.server.Addr)
// 监听context取消信号
shutdownChan := make(chan struct{})
go func() {
<-ctx.Done()
log.Println("接收到context取消信号开始关闭服务器...")
close(shutdownChan)
}()
s.wg.Add(1)
go func() {
defer s.wg.Done()
if err := s.server.ListenAndServe(); err != nil && !errors.Is(err, http.ErrServerClosed) {
log.Printf("服务器启动失败: %v", err)
return
}
}()
// 给服务器一点启动时间
time.Sleep(100 * time.Millisecond)
// 等待服务器启动完成或context取消
select {
case <-shutdownChan:
// 如果context在启动过程中被取消立即关闭服务器
if err := s.Stop(); err != nil {
log.Printf("启动过程中关闭服务器失败: %v", err)
}
return ctx.Err()
default:
log.Println("HTTP服务器启动成功")
return nil
}
}
// Stop 优雅关闭HTTP服务器
func (s *HTTPServer) Stop() error {
log.Println("正在关闭HTTP服务器...")
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
if err := s.server.Shutdown(ctx); err != nil {
return fmt.Errorf("服务器关闭失败: %v", err)
}
// 等待服务器协程结束
s.wg.Wait()
log.Println("HTTP服务器已成功关闭")
return nil
}
// StartWithContext 可选:提供一个更简洁的启动方法(如果你需要)
func (s *HTTPServer) StartWithContext(ctx context.Context) <-chan error {
errChan := make(chan error, 1)
go func() {
errChan <- s.Start(ctx)
close(errChan)
}()
return errChan
}