-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain.go
More file actions
135 lines (108 loc) · 3.3 KB
/
main.go
File metadata and controls
135 lines (108 loc) · 3.3 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
package main
import (
"context"
"fmt"
"net/http"
"os"
"os/signal"
"syscall"
"time"
"notion-proxy/config"
"notion-proxy/handlers"
"notion-proxy/middleware"
"notion-proxy/models"
"notion-proxy/services"
"notion-proxy/utils"
"github.com/gin-gonic/gin"
"github.com/joho/godotenv"
)
var serverLogger = utils.NewLogger("Server")
func main() {
// 加载环境变量
godotenv.Load()
// 加载配置
cfg := config.Load()
// 创建Notion服务
notionService, err := services.NewNotionService(cfg)
if err != nil {
serverLogger.Error("创建Notion服务失败: %v", err)
os.Exit(1)
}
// 创建处理器
chatHandler := handlers.NewChatHandler(notionService)
// 设置Gin模式
gin.SetMode(gin.ReleaseMode)
// 创建路由
router := gin.New()
// 设置中间件
router.Use(gin.Recovery())
router.Use(middleware.RequestLogger())
router.Use(corsMiddleware())
// 设置路由
setupRoutes(router, chatHandler)
// 创建HTTP服务器
server := &http.Server{
Addr: fmt.Sprintf(":%d", cfg.Port),
Handler: router,
ReadTimeout: 120 * time.Second,
WriteTimeout: 120 * time.Second,
}
// 启动服务器
go func() {
serverLogger.Server("正在启动Notion API代理服务器...")
serverLogger.Info("认证方式: 外部Cookie(cookie:userId:spaceId)")
serverLogger.Success("服务已启动 - 端口: %d", cfg.Port)
serverLogger.Info("访问地址: http://localhost:%d", cfg.Port)
serverLogger.Success("服务器启动完成,准备接收请求")
if err := server.ListenAndServe(); err != nil && err != http.ErrServerClosed {
serverLogger.Error("服务器启动失败: %v", err)
os.Exit(1)
}
}()
// 优雅关闭
gracefulShutdown(server)
}
// setupRoutes 设置路由
func setupRoutes(router *gin.Engine, chatHandler *handlers.ChatHandler) {
// 根路径 - 重定向到哔哩哔哩视频
router.GET("/", func(c *gin.Context) {
c.Redirect(http.StatusMovedPermanently, "https://www.bilibili.com/video/BV1p44y1m7Fk")
})
// 聊天完成API
router.POST("/v1/chat/completions", middleware.Authenticate(), chatHandler.HandleChatCompletions)
// 404处理
router.NoRoute(func(c *gin.Context) {
c.JSON(http.StatusNotFound, models.ErrorResponse{
Error: models.ErrorDetail{
Message: fmt.Sprintf("Route %s %s not found", c.Request.Method, c.Request.URL.Path),
Type: "not_found_error",
},
})
})
}
// corsMiddleware CORS中间件
func corsMiddleware() gin.HandlerFunc {
return func(c *gin.Context) {
c.Header("Access-Control-Allow-Origin", "*")
c.Header("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS")
c.Header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, Authorization, X-Client-Id")
if c.Request.Method == "OPTIONS" {
c.AbortWithStatus(http.StatusOK)
return
}
c.Next()
}
}
// gracefulShutdown 优雅关闭
func gracefulShutdown(server *http.Server) {
quit := make(chan os.Signal, 1)
signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM, syscall.SIGQUIT)
sig := <-quit
serverLogger.Server("收到%v信号,正在优雅关闭服务器...", sig)
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
defer cancel()
if err := server.Shutdown(ctx); err != nil {
serverLogger.Error("服务器关闭出错: %v", err)
}
serverLogger.Success("服务器优雅关闭完成")
}