package main import ( "ChatRoom/internal/rabbitmq" "ChatRoom/internal/redis" "ChatRoom/internal/ws" "log" "net/http" "os" "path/filepath" "time" ) func main() { // 1. 初始化 RabbitMQ rabbitmqURL := os.Getenv("RABBITMQ_URL") if rabbitmqURL == "" { // 默认使用本地 Docker 启动的 RabbitMQ 配置 (admin/1218Zhengyaqi) rabbitmqURL = "amqp://admin:1218Zhengyaqi@localhost:5672/" } var rmq *rabbitmq.Client var err error maxRetries := 30 for i := 0; i < maxRetries; i++ { rmq, err = rabbitmq.NewClient(rabbitmqURL) if err == nil { break } // 如果是 403 认证错误,重试也没用,直接报错退出 if err.Error() == "Exception (403) Reason: \"username or password not allowed\"" { log.Fatalf("RabbitMQ 认证失败,请检查账号密码: %v", err) } log.Printf("RabbitMQ 连接失败 (尝试 %d/%d): %v, 2秒后重试...", i+1, maxRetries, err) time.Sleep(2 * time.Second) } if err != nil { log.Fatalf("RabbitMQ 连接最终失败: %v", err) } defer rmq.Close() // 1.5 初始化 Redis redisAddr := os.Getenv("REDIS_ADDR") if redisAddr == "" { redisAddr = "localhost:6379" } redisClient, err := redis.NewClient(redisAddr, "", 0) if err != nil { log.Fatalf("Redis 连接失败: %v", err) } defer redisClient.Close() // 2. WebSocket 路由 http.HandleFunc("/ws", func(w http.ResponseWriter, r *http.Request) { ws.NewConnection(w, r, rmq, redisClient) // 传入 RabbitMQ 和 Redis 客户端 }) // 3. 静态文件服务(用于测试前端) webDir := "./web" if _, err := os.Stat(webDir); os.IsNotExist(err) { // 从 cmd/server 目录运行时,web 在项目根目录 webDir = filepath.Join("..", "..", "web") } http.Handle("/", http.FileServer(http.Dir(webDir))) // 4. 启动服务 port := os.Getenv("PORT") if port == "" { port = "8080" } log.Printf("服务启动: http://localhost:%s", port) log.Fatal(http.ListenAndServe(":"+port, nil)) }