Initial commit
This commit is contained in:
162
main.go
Normal file
162
main.go
Normal file
@@ -0,0 +1,162 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"flag"
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
"os/signal"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"jwts/auth"
|
||||
"jwts/captcha"
|
||||
"jwts/client"
|
||||
"jwts/config"
|
||||
grpcClient "jwts/grpc"
|
||||
"jwts/parser"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
func main() {
|
||||
mode := flag.String("mode", "http", "运行模式: http 或 grpc")
|
||||
grpcAddr := flag.String("grpc-addr", "localhost:50051", "gRPC 服务器地址")
|
||||
flag.Parse()
|
||||
|
||||
if *mode == "grpc" {
|
||||
runGRPCClient(*grpcAddr)
|
||||
} else {
|
||||
runHTTPServer()
|
||||
}
|
||||
}
|
||||
|
||||
// runGRPCClient 运行 gRPC 客户端模式
|
||||
func runGRPCClient(serverAddr string) {
|
||||
runnerID := os.Getenv("RUNNER_ID")
|
||||
if runnerID == "" {
|
||||
hostname, _ := os.Hostname()
|
||||
runnerID = "runner-" + hostname
|
||||
}
|
||||
|
||||
version := os.Getenv("RUNNER_VERSION")
|
||||
if version == "" {
|
||||
version = "1.0.0"
|
||||
}
|
||||
|
||||
log.Printf("启动 gRPC 客户端, Runner ID: %s, 版本: %s", runnerID, version)
|
||||
|
||||
client := grpcClient.NewClient(serverAddr, runnerID, version)
|
||||
handler := grpcClient.NewTaskHandler()
|
||||
client.SetHandler(handler)
|
||||
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
|
||||
// 处理信号
|
||||
sigChan := make(chan os.Signal, 1)
|
||||
signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM)
|
||||
|
||||
if err := client.Connect(ctx); err != nil {
|
||||
log.Printf("连接失败: %v", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
go func() {
|
||||
<-sigChan
|
||||
log.Println("正在关闭...")
|
||||
client.Close()
|
||||
cancel()
|
||||
}()
|
||||
|
||||
// 启动心跳
|
||||
go client.HeartbeatLoop(ctx, 30*time.Second)
|
||||
|
||||
// 运行主循环
|
||||
if err := client.Run(ctx); err != nil {
|
||||
log.Printf("客户端错误: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
// runHTTPServer 运行 HTTP 服务器模式
|
||||
func runHTTPServer() {
|
||||
// 初始化客户端
|
||||
client.InitClient()
|
||||
|
||||
r := gin.Default()
|
||||
|
||||
// 健康检查接口
|
||||
r.GET("/ping", func(c *gin.Context) {
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"message": "pong",
|
||||
})
|
||||
})
|
||||
|
||||
// 任务处理接口
|
||||
r.POST("/task", func(c *gin.Context) {
|
||||
// 这里可以根据请求体参数决定执行什么任务
|
||||
// 目前默认执行原有的登录和获取课表逻辑
|
||||
if config.Username == "" || config.Password == "" {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": "环境变量未设置"})
|
||||
return
|
||||
}
|
||||
|
||||
// 执行任务
|
||||
err := runTask()
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, gin.H{"message": "任务执行成功"})
|
||||
})
|
||||
|
||||
// 启动服务
|
||||
log.Println("Server starting on :8080")
|
||||
if err := r.Run(":8080"); err != nil {
|
||||
log.Fatalf("Failed to run server: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func runTask() error {
|
||||
// 步骤1: 获取初始Cookie
|
||||
err := client.GetInitialCookies()
|
||||
if err != nil {
|
||||
log.Printf("获取Cookie失败: %v", err)
|
||||
return err
|
||||
}
|
||||
|
||||
// 重试登录
|
||||
maxRetries := 3
|
||||
for attempt := 1; attempt <= maxRetries; attempt++ {
|
||||
log.Printf("尝试登录 (第%d次)...", attempt)
|
||||
|
||||
// 获取并识别验证码
|
||||
captchaCode, err := captcha.GetAndRecognize(client.Client)
|
||||
if err != nil {
|
||||
log.Printf(" 验证码获取失败: %v", err)
|
||||
continue
|
||||
}
|
||||
|
||||
// 登录
|
||||
success, err := auth.Login(captchaCode)
|
||||
if err != nil {
|
||||
log.Printf(" 登录失败: %v", err)
|
||||
continue
|
||||
}
|
||||
|
||||
if success {
|
||||
// 获取课表
|
||||
_, err = parser.FetchSchedule(client.Client)
|
||||
if err != nil {
|
||||
log.Printf("获取课表失败: %v", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
log.Println(" 登录失败,3秒后重试...")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
Reference in New Issue
Block a user