Browse Source

npc service init

刘河 5 years ago
parent
commit
d930d9f003
2 changed files with 113 additions and 22 deletions
  1. 102 22
      cmd/npc/npc.go
  2. 11 0
      lib/common/run.go

+ 102 - 22
cmd/npc/npc.go

@@ -3,18 +3,18 @@ package main
 import (
 	"flag"
 	"fmt"
-	"os"
-	"strings"
-	"time"
-
 	"github.com/astaxie/beego/logs"
 	"github.com/ccding/go-stun/stun"
 	"github.com/cnlh/nps/client"
 	"github.com/cnlh/nps/lib/common"
 	"github.com/cnlh/nps/lib/config"
-	"github.com/cnlh/nps/lib/daemon"
 	"github.com/cnlh/nps/lib/file"
 	"github.com/cnlh/nps/lib/version"
+	"github.com/kardianos/service"
+	"os"
+	"runtime"
+	"strings"
+	"time"
 )
 
 var (
@@ -30,11 +30,56 @@ var (
 	password     = flag.String("password", "", "p2p password flag")
 	target       = flag.String("target", "", "p2p target")
 	localType    = flag.String("local_type", "p2p", "p2p target")
-	logPath      = flag.String("log_path", "npc.log", "npc log path")
+	logPath      = flag.String("log_path", "", "npc log path")
+	debug        = flag.Bool("debug", false, "npc debug")
+	srv          = flag.String("service", "", "npc debug")
 )
 
 func main() {
 	flag.Parse()
+	logs.Reset()
+	logs.EnableFuncCallDepth(true)
+	logs.SetLogFuncCallDepth(3)
+	if *logPath == "" {
+		*logPath = common.GetNpcLogPath()
+	}
+	if common.IsWindows() {
+		*logPath = strings.Replace(*logPath, "\\", "\\\\", -1)
+	}
+	if *debug {
+		logs.SetLogger(logs.AdapterConsole, `{"level":`+*logLevel+`,"color":true}`)
+	} else {
+		logs.SetLogger(logs.AdapterFile, `{"level":`+*logLevel+`,"filename":"`+*logPath+`","daily":false,"maxlines":100000,"color":true}`)
+	}
+
+	// init service
+	options := make(service.KeyValue)
+	options["Restart"] = "on-success"
+	options["SuccessExitStatus"] = "1 2 8 SIGKILL"
+	svcConfig := &service.Config{
+		Name:        "Npc",
+		DisplayName: "nps内网穿透客户端",
+		Description: "一款轻量级、功能强大的内网穿透代理服务器。支持tcp、udp流量转发,支持内网http代理、内网socks5代理,同时支持snappy压缩、站点保护、加密传输、多路复用、header修改等。支持web图形化管理,集成多用户模式。",
+		Option:      options,
+	}
+	if !common.IsWindows() {
+		svcConfig.Dependencies = []string{
+			"Requires=network.target",
+			"After=network-online.target syslog.target"}
+	}
+	for _, v := range os.Args[1:] {
+		if !strings.Contains(v, "-service=") {
+			svcConfig.Arguments = append(svcConfig.Arguments, v)
+		}
+	}
+	prg := &npc{
+		exit: make(chan struct{}),
+	}
+	s, err := service.New(prg, svcConfig)
+	if err != nil {
+		logs.Error(err)
+		return
+	}
 	if len(os.Args) >= 2 {
 		switch os.Args[1] {
 		case "status":
@@ -55,14 +100,42 @@ func main() {
 			os.Exit(0)
 		}
 	}
-	daemon.InitDaemon("npc", common.GetRunPath(), common.GetTmpPath())
-	logs.EnableFuncCallDepth(true)
-	logs.SetLogFuncCallDepth(3)
-	if *logType == "stdout" {
-		logs.SetLogger(logs.AdapterConsole, `{"level":`+*logLevel+`,"color":true}`)
-	} else {
-		logs.SetLogger(logs.AdapterFile, `{"level":`+*logLevel+`,"filename":"`+*logPath+`","daily":false,"maxlines":100000,"color":true}`)
+
+	if *srv != "" {
+		err := service.Control(s, *srv)
+		if err != nil {
+			logs.Error("Valid actions: %q\n", service.ControlAction, err.Error())
+		}
+		return
+	}
+	s.Run()
+}
+
+type npc struct {
+	exit chan struct{}
+}
+
+func (p *npc) Start(s service.Service) error {
+	p.run()
+	return nil
+}
+func (p *npc) Stop(s service.Service) error {
+	close(p.exit)
+	if service.Interactive() {
+		os.Exit(0)
 	}
+	return nil
+}
+
+func (p *npc) run() error {
+	defer func() {
+		if err := recover(); err != nil {
+			const size = 64 << 10
+			buf := make([]byte, size)
+			buf = buf[:runtime.Stack(buf, false)]
+			logs.Warning("npc: panic serving %v: %v\n%s", err, string(buf))
+		}
+	}()
 	//p2p or secret command
 	if *password != "" {
 		commonConfig := new(config.CommonConfig)
@@ -76,8 +149,8 @@ func main() {
 		localServer.Port = *localPort
 		commonConfig.Client = new(file.Client)
 		commonConfig.Client.Cnf = new(file.Config)
-		client.StartLocalServer(localServer, commonConfig)
-		return
+		go client.StartLocalServer(localServer, commonConfig)
+		return nil
 	}
 	env := common.GetEnvMap()
 	if *serverAddr == "" {
@@ -88,15 +161,22 @@ func main() {
 	}
 	logs.Info("the version of client is %s, the core version of client is %s", version.VERSION, version.GetVersion())
 	if *verifyKey != "" && *serverAddr != "" && *configPath == "" {
-		for {
-			client.NewRPClient(*serverAddr, *verifyKey, *connType, *proxyUrl, nil).Start()
-			logs.Info("It will be reconnected in five seconds")
-			time.Sleep(time.Second * 5)
-		}
+		go func() {
+			for {
+				client.NewRPClient(*serverAddr, *verifyKey, *connType, *proxyUrl, nil).Start()
+				logs.Info("It will be reconnected in five seconds")
+				time.Sleep(time.Second * 5)
+			}
+		}()
 	} else {
 		if *configPath == "" {
-			*configPath = "npc.conf"
+			*configPath = "conf/npc.conf"
 		}
-		client.StartFromFile(*configPath)
+		go client.StartFromFile(*configPath)
+	}
+	select {
+	case <-p.exit:
+		logs.Warning("stop...")
 	}
+	return nil
 }

+ 11 - 0
lib/common/run.go

@@ -55,6 +55,17 @@ func GetLogPath() string {
 	return path
 }
 
+//interface npc log file path
+func GetNpcLogPath() string {
+	var path string
+	if IsWindows() {
+		path = filepath.Join(GetAppPath(), "npc.log")
+	} else {
+		path = "/var/log/npc.log"
+	}
+	return path
+}
+
 //interface pid file path
 func GetTmpPath() string {
 	var path string