netplay-lobby-server-go/main.go
2024-12-24 22:09:17 +08:00

127 lines
3.5 KiB
Go

package main
import (
"flag"
"fmt"
"time"
"github.com/jinzhu/gorm"
"github.com/labstack/echo/v4"
"github.com/labstack/echo/v4/middleware"
"github.com/labstack/gommon/log"
"github.com/spf13/viper"
"github.com/libretro/netplay-lobby-server-go/controller"
"github.com/libretro/netplay-lobby-server-go/domain"
"github.com/libretro/netplay-lobby-server-go/model"
"github.com/libretro/netplay-lobby-server-go/model/entity"
"github.com/libretro/netplay-lobby-server-go/model/repository"
)
func main() {
var verbose = flag.Bool("v", false, "详细日志记录")
flag.Parse()
server := echo.New()
server.HideBanner = true
server.Server.ReadTimeout = 5 * time.Second
server.Server.WriteTimeout = 5 * time.Second
config, err := readConfig()
if err != nil {
server.Logger.Fatalf("无法获取配置值: %v", err)
}
// 初始化领域逻辑和模型
db, err := initDatabase(config.Database.Type, config.Database.Connection)
if err != nil {
server.Logger.Fatalf("无法初始化数据库: %v", err)
}
db = db.AutoMigrate(&entity.Session{})
if *verbose {
server.Logger.SetLevel(log.INFO)
} else {
server.Logger.SetLevel(log.WARN)
}
sessionDomain, err := initDomain(db, config)
if err != nil {
server.Logger.Fatalf("无法初始化领域逻辑: %v", err)
}
sessionCotroller := controller.NewSessionController(sessionDomain)
// 启动清理作业以清除旧会话
go func() {
for true {
err := sessionDomain.PurgeOld()
if err != nil {
server.Logger.Fatalf("无法清除旧会话: %v", err)
}
time.Sleep(2 * time.Minute)
}
}()
// 服务器设置
server.Use(middleware.Logger())
server.Use(middleware.Recover())
server.Use(middleware.BodyLimit("64K"))
// 设置路由和预渲染模板
sessionCotroller.RegisterRoutes(server)
templatePath := fmt.Sprintf("%s/*.html", config.Server.TemplatePath)
if err = sessionCotroller.PrerenderTemplates(server, templatePath); err != nil {
server.Logger.Fatalf("无法预渲染模板: %v", err)
}
// 开始服务
server.Logger.Fatal(server.Start(config.Server.Address))
}
func readConfig() (*Config, error) {
viper := viper.New()
viper.SetConfigName("lobby")
viper.SetConfigType("yaml")
viper.AddConfigPath("/etc/lobby")
viper.AddConfigPath("$HOME/.lobby")
viper.AddConfigPath("./config")
if err := viper.ReadInConfig(); err != nil {
return nil, fmt.Errorf("无法读取配置文件: %w", err)
}
var conf Config
if err := viper.Unmarshal(&conf); err != nil {
return nil, fmt.Errorf("无法解组配置文件: %w", err)
}
return &conf, nil
}
func initDatabase(databaseType string, connectionString string) (*gorm.DB, error) {
switch databaseType {
case "mysql":
return model.GetMysqlDB(connectionString)
case "postgres":
return model.GetPostgreDB(connectionString)
case "sqlite":
return model.GetSqliteDB(connectionString)
}
return nil, fmt.Errorf("配置中未知的数据库类型: %s", databaseType)
}
func initDomain(db *gorm.DB, config *Config) (*domain.SessionDomain, error) {
repo := repository.NewSessionRepository(db)
geo2Domain, err := domain.NewGeoIP2Domain(config.Server.GeoLite2Path)
if err != nil {
return nil, fmt.Errorf("无法初始化 GeoLite2 数据库: %w", err)
}
validationDomain, err := domain.NewValidationDomain(config.Blacklist.Strings, config.Blacklist.IPs)
if err != nil {
return nil, fmt.Errorf("无法初始化验证域: %w", err)
}
mitmDomain := domain.NewMitmDomain(config.Relay)
sessionDomain := domain.NewSessionDomain(repo, geo2Domain, validationDomain, mitmDomain)
return sessionDomain, nil
}