Browse Source

add: 控制frpc进程

master
pcong 5 months ago
parent
commit
9dadc39725
  1. 9
      godo/cmd/main.go
  2. 55
      godo/progress/progress.go
  3. 59
      godo/proxy/frpc_service.go

9
godo/cmd/main.go

@ -171,10 +171,13 @@ func OsStart() {
// 注册frpc路由
frpcRouter := router.PathPrefix("/frpc").Subrouter()
frpcRouter.HandleFunc("/create", proxy.CreateFrpcHandler).Methods(http.MethodPost)
frpcRouter.HandleFunc("/delete", proxy.DeleteFrpcConfigHandler).Methods(http.MethodGet) // 删除frpc配置
frpcRouter.HandleFunc("/get", proxy.GetFrpcConfigHandler).Methods(http.MethodGet) // 获取frpc配置
frpcRouter.HandleFunc("/list", proxy.GetFrpcProxiesHandler).Methods(http.MethodGet) // 获取frpc代理列表
frpcRouter.HandleFunc("/delete", proxy.DeleteFrpcConfigHandler).Methods(http.MethodGet) // 删除frpc配置
frpcRouter.HandleFunc("/get", proxy.GetFrpcConfigHandler).Methods(http.MethodGet) // 获取frpc配置
frpcRouter.HandleFunc("/list", proxy.GetFrpcProxiesHandler).Methods(http.MethodGet) // 获取frpc代理列表
frpcRouter.HandleFunc("/update", proxy.UpdateFrpcConfigHandler).Methods(http.MethodPost) // 更新frpc配置
frpcRouter.HandleFunc("/start", proxy.StartFrpcHandler).Methods(http.MethodPost) // 启动frpc服务
frpcRouter.HandleFunc("/stop", proxy.StopFrpcHandler).Methods(http.MethodPost) // 停止frpc服务
frpcRouter.HandleFunc("/restart", proxy.RestartFrpcHandler).Methods(http.MethodPost) // 重启frpc服务
// 注册根路径的处理函数
distFS, _ := fs.Sub(deps.Frontendassets, "dist")

55
godo/progress/progress.go

@ -10,13 +10,18 @@ import (
"os/exec"
"path/filepath"
"runtime"
"strconv"
"strings"
"sync"
"github.com/shirou/gopsutil/process"
)
type Process struct {
Name string
Running bool
ExitCode int
Pid int
Cmd *exec.Cmd
}
@ -31,6 +36,7 @@ func RegisterProcess(name string, cmdstr *exec.Cmd) {
processes[name] = &Process{
Name: name,
Running: true,
Pid: cmdstr.Process.Pid,
Cmd: cmdstr,
}
}
@ -121,15 +127,24 @@ func StopCmd(name string) error {
if !ok {
return fmt.Errorf("process information for '%s' not found", name)
}
if cmd.Running == false {
return nil
}
// 停止进程并更新status
if err := cmd.Cmd.Process.Kill(); err != nil {
// TODO: 如果有多个pid 的情况,需要处理
if err := KillByPid(cmd.Pid); err != nil {
return fmt.Errorf("failed to kill process %s: %v", name, err)
}
// if err := cmd.Cmd.Process.Kill(); err != nil {
// return fmt.Errorf("failed to kill process %s: %v", name, err)
// }
//delete(processes, name) // 更新status,表示进程已停止
cmd.Running = false
return nil
}
func RestartCmd(name string) error {
if err := StopCmd(name); err != nil {
return err
@ -147,3 +162,41 @@ func StopAllCmd() error {
}
return nil
}
func KillByPid(pid int) error {
log.Println("Killing process with PID:", pid)
p, err := process.NewProcess(int32(pid))
if err != nil {
return fmt.Errorf("failed to create process object: %w", err)
}
// 杀死进程及其子进程
if err := p.Kill(); err != nil {
return fmt.Errorf("failed to kill process: %w", err)
}
return nil
}
// findPidsWindows 在 Windows 系统下查找具有指定名称的进程的 PID
func findPidsWindows(name string) ([]int, error) {
cmd := exec.Command("tasklist")
output, err := cmd.Output()
if err != nil {
return nil, fmt.Errorf("failed to execute tasklist: %w", err)
}
lines := strings.Split(string(output), "\r\n")
var pids []int
for _, line := range lines {
fields := strings.Fields(line)
if len(fields) >= 3 {
if strings.Contains(strings.ToLower(fields[0]), strings.ToLower(name)) {
pid, err := strconv.Atoi(fields[1])
if err != nil {
return nil, fmt.Errorf("failed to convert PID to integer: %w", err)
}
pids = append(pids, pid)
}
}
}
return pids, nil
}

59
godo/proxy/frpc_service.go

@ -0,0 +1,59 @@
package proxy
import (
"encoding/json"
"godo/progress"
"log"
"net/http"
)
func StartFrpcHandler(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodPost {
http.Error(w, "Invalid request method", http.StatusMethodNotAllowed)
return
}
if err := progress.StartCmd("frpc"); err != nil {
log.Printf("Failed to start frpc service: %v", err)
http.Error(w, "Failed to start frpc service", http.StatusInternalServerError)
return
}
response := NewResponse("0", "frpc service started", nil)
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(response)
}
func StopFrpcHandler(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodPost {
http.Error(w, "Invalid request method", http.StatusMethodNotAllowed)
return
}
if err := progress.StopCmd("frpc"); err != nil {
log.Printf("Failed to stop frpc service: %v", err)
http.Error(w, "Failed to stop frpc service", http.StatusInternalServerError)
return
}
response := NewResponse("0", "frpc service stoped", nil)
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(response)
}
func RestartFrpcHandler(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodPost {
http.Error(w, "Invalid request method", http.StatusMethodNotAllowed)
return
}
if err := progress.RestartCmd("frpc"); err != nil {
log.Printf("Failed to restarted frpc service: %v", err)
http.Error(w, "Failed to restarted frpc service", http.StatusInternalServerError)
return
}
response := NewResponse("0", "frpc service restarted", nil)
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(response)
}
Loading…
Cancel
Save