StartServer 启动Web服务器
(port int)
| 24 | |
| 25 | // StartServer 启动Web服务器 |
| 26 | func StartServer(port int) error { |
| 27 | // 初始化WebSocket Hub |
| 28 | hub := ws.NewHub() |
| 29 | go hub.Run() |
| 30 | |
| 31 | // 创建路由 |
| 32 | mux := http.NewServeMux() |
| 33 | |
| 34 | // API路由 |
| 35 | api.RegisterRoutes(mux, hub) |
| 36 | |
| 37 | // WebSocket路由 |
| 38 | mux.HandleFunc("/ws", func(w http.ResponseWriter, r *http.Request) { |
| 39 | ws.ServeWs(hub, w, r) |
| 40 | }) |
| 41 | |
| 42 | // 静态文件服务 |
| 43 | distContent, err := fs.Sub(distFS, "dist") |
| 44 | if err != nil { |
| 45 | return fmt.Errorf("failed to get dist fs: %w", err) |
| 46 | } |
| 47 | fileServer := http.FileServer(http.FS(distContent)) |
| 48 | |
| 49 | // SPA fallback: 对于非API/WS请求,尝试静态文件,否则返回index.html |
| 50 | mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { |
| 51 | // 检查文件是否存在 |
| 52 | path := r.URL.Path |
| 53 | if path == "/" { |
| 54 | path = "/index.html" |
| 55 | } |
| 56 | |
| 57 | // 尝试打开文件 |
| 58 | f, err := distContent.Open(path[1:]) // 移除开头的/ |
| 59 | if err != nil { |
| 60 | // 文件不存在,返回index.html(SPA路由) |
| 61 | r.URL.Path = "/" |
| 62 | fileServer.ServeHTTP(w, r) |
| 63 | return |
| 64 | } |
| 65 | f.Close() |
| 66 | |
| 67 | // 文件存在,正常服务 |
| 68 | fileServer.ServeHTTP(w, r) |
| 69 | }) |
| 70 | |
| 71 | // 创建服务器 |
| 72 | addr := fmt.Sprintf(":%d", port) |
| 73 | server := &http.Server{ |
| 74 | Addr: addr, |
| 75 | Handler: corsMiddleware(mux), |
| 76 | ReadTimeout: 30 * time.Second, |
| 77 | WriteTimeout: 30 * time.Second, |
| 78 | IdleTimeout: 60 * time.Second, |
| 79 | } |
| 80 | |
| 81 | // 优雅关闭 |
| 82 | done := make(chan bool) |
| 83 | quit := make(chan os.Signal, 1) |
nothing calls this directly
no test coverage detected