174 lines
4.5 KiB
Go
174 lines
4.5 KiB
Go
package main
|
||
|
||
import (
|
||
"database/sql"
|
||
"errors"
|
||
"fmt"
|
||
"github.com/gin-gonic/gin"
|
||
_ "github.com/mattn/go-sqlite3"
|
||
"log"
|
||
"net/http"
|
||
"time"
|
||
)
|
||
|
||
// MappingInfo 用于存储映射信息
|
||
type MappingInfo struct {
|
||
RuleName string `json:"rule_name"`
|
||
IpAddr string `json:"ip_addr"`
|
||
Ip string `json:"ip"`
|
||
Port string `json:"port"`
|
||
LastUpdate time.Time `json:"last_update"`
|
||
}
|
||
|
||
// 全局变量,存储所有映射信息
|
||
var mappings = make(map[string]*MappingInfo)
|
||
|
||
var db *sql.DB
|
||
var dbFileName = "./mappings.db" // 数据库文件名
|
||
var tableName = "mappings" // 数据库表名
|
||
var query = `SELECT name FROM sqlite_master WHERE type='table' AND name=?;` // 查询表是否存在的SQL语句
|
||
var createTableSQL = `CREATE TABLE IF NOT EXISTS ` + tableName + ` (
|
||
"RuleName" TEXT PRIMARY KEY,
|
||
"IPAddress" TEXT,
|
||
"Ip" TEXT,
|
||
"Port" TEXT,
|
||
"LastUpdate" TEXT
|
||
);` // 创建表的SQL语句
|
||
|
||
func main() {
|
||
InitDB() // 初始化数据库
|
||
defer func(db *sql.DB) {
|
||
err := db.Close()
|
||
if err != nil {
|
||
log.Fatal(err)
|
||
}
|
||
}(db)
|
||
|
||
router := gin.Default()
|
||
|
||
// 处理Webhook的路由
|
||
router.POST("/webhook", func(c *gin.Context) {
|
||
var info MappingInfo
|
||
if err := c.BindJSON(&info); err != nil {
|
||
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
||
return
|
||
}
|
||
info.LastUpdate = time.Now()
|
||
// 输出一下info
|
||
fmt.Println(info)
|
||
mappings[info.RuleName] = &info
|
||
updateMapping(info) // 更新数据库中的映射信息
|
||
c.JSON(http.StatusOK, gin.H{"status": "updated"})
|
||
})
|
||
|
||
// 提供Web服务的路由,展示映射信息
|
||
router.GET("/mappings", func(c *gin.Context) {
|
||
c.JSON(http.StatusOK, mappings)
|
||
})
|
||
|
||
// 根据RuleName查询映射信息
|
||
router.GET("/mappings/:RuleName", func(c *gin.Context) {
|
||
serviceName := c.Param("RuleName")
|
||
if info, exists := mappings[serviceName]; exists {
|
||
c.JSON(http.StatusOK, info)
|
||
} else {
|
||
c.JSON(http.StatusNotFound, gin.H{"code": http.StatusNotFound, "error": "service not found"})
|
||
}
|
||
})
|
||
|
||
// 根据RuleName跳转到映射的服务
|
||
router.GET("/:RuleName", func(c *gin.Context) {
|
||
serviceName := c.Param("RuleName")
|
||
if info, exists := mappings[serviceName]; exists {
|
||
url := "http://" + info.Ip + ":" + info.Port
|
||
c.Redirect(http.StatusMovedPermanently, url)
|
||
} else {
|
||
c.JSON(http.StatusNotFound, gin.H{"code": http.StatusNotFound, "error": "service not found"})
|
||
}
|
||
})
|
||
|
||
// 启动定时任务,检查映射信息更新
|
||
go checkMappings()
|
||
|
||
err := router.Run(":8080")
|
||
if err != nil {
|
||
return
|
||
} // 在8080端口启动服务
|
||
}
|
||
|
||
// 定时检查映射信息是否需要更新
|
||
func checkMappings() {
|
||
for {
|
||
time.Sleep(24 * time.Hour) // 每天检查一次
|
||
for _, info := range mappings {
|
||
if time.Since(info.LastUpdate) > 24*time.Hour {
|
||
// 如果超过一天没有更新,则主动查询API(这里需要实现API查询逻辑)
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
func InitDB() {
|
||
log.Println("Init DB...")
|
||
var err error
|
||
db, err = sql.Open("sqlite3", dbFileName)
|
||
if err != nil {
|
||
log.Fatal(err)
|
||
}
|
||
|
||
err = db.QueryRow(query, tableName).Scan(&tableName)
|
||
if errors.Is(err, sql.ErrNoRows) {
|
||
log.Println("Table not exists, create it...")
|
||
createTable()
|
||
} else if err != nil {
|
||
log.Fatal(err)
|
||
} else {
|
||
// 读取数据库中的映射信息
|
||
mappings = readMappings()
|
||
fmt.Println(mappings)
|
||
}
|
||
log.Println("Init DB done.")
|
||
}
|
||
|
||
// 创建映射表
|
||
func createTable() {
|
||
_, err := db.Exec(createTableSQL)
|
||
if err != nil {
|
||
log.Fatal(err)
|
||
}
|
||
}
|
||
|
||
// 从数据库读取映射信息
|
||
func readMappings() map[string]*MappingInfo {
|
||
mappings := make(map[string]*MappingInfo)
|
||
rows, err := db.Query("SELECT RuleName, IPAddress, Ip, Port, LastUpdate FROM mappings")
|
||
if err != nil {
|
||
log.Fatal(err)
|
||
}
|
||
defer rows.Close()
|
||
|
||
for rows.Next() {
|
||
var info MappingInfo
|
||
var lastUpdate string
|
||
err = rows.Scan(&info.RuleName, &info.IpAddr, &info.Ip, &info.Port, &lastUpdate)
|
||
if err != nil {
|
||
log.Fatal(err)
|
||
}
|
||
info.LastUpdate, err = time.Parse(time.RFC3339, lastUpdate)
|
||
if err != nil {
|
||
log.Fatal(err)
|
||
}
|
||
mappings[info.RuleName] = &info
|
||
}
|
||
return mappings
|
||
}
|
||
|
||
// 更新数据库中的映射信息
|
||
func updateMapping(info MappingInfo) {
|
||
_, err := db.Exec("INSERT OR REPLACE INTO mappings (RuleName, IPAddress, Ip, Port, LastUpdate) VALUES (?, ?, ?, ?, ?)",
|
||
info.RuleName, info.IpAddr, info.Ip, info.Port, info.LastUpdate.Format(time.RFC3339))
|
||
if err != nil {
|
||
log.Fatal(err)
|
||
}
|
||
}
|