gitee.com/quant1x/gox@v1.21.2/daemon/examples/myservice.go (about) 1 // Example of a daemon with echo service 2 package main 3 4 import ( 5 "fmt" 6 "gitee.com/quant1x/gox/daemon" 7 "log" 8 "net" 9 "os" 10 "os/signal" 11 "syscall" 12 ) 13 14 const ( 15 16 // name of the service 17 name = "myservice" 18 description = "My Echo Service" 19 20 // port which daemon should be listen 21 port = ":9977" 22 ) 23 24 // dependencies that are NOT required by the service, but might be used 25 var dependencies = []string{"dummy.service"} 26 27 var stdlog, errlog *log.Logger 28 29 // Service has embedded daemon 30 type Service struct { 31 daemon.Daemon 32 } 33 34 // Manage by daemon commands or run the daemon 35 func (service *Service) Manage() (string, error) { 36 37 usage := "Usage: myservice install | remove | start | stop | status" 38 39 // if received any kind of command, do it 40 if len(os.Args) > 1 { 41 command := os.Args[1] 42 switch command { 43 case "install": 44 return service.Install() 45 case "remove": 46 return service.Remove() 47 case "start": 48 return service.Start() 49 case "stop": 50 return service.Stop() 51 case "status": 52 return service.Status() 53 default: 54 return usage, nil 55 } 56 } 57 58 // Do something, call your goroutines, etc 59 60 // Set up channel on which to send signal notifications. 61 // We must use a buffered channel or risk missing the signal 62 // if we're not ready to receive when the signal is sent. 63 interrupt := make(chan os.Signal, 1) 64 signal.Notify(interrupt, os.Interrupt, os.Kill, syscall.SIGTERM) 65 66 // Set up listener for defined host and port 67 listener, err := net.Listen("tcp", port) 68 if err != nil { 69 return "Possibly was a problem with the port binding", err 70 } 71 72 // set up channel on which to send accepted connections 73 listen := make(chan net.Conn, 100) 74 go acceptConnection(listener, listen) 75 76 // loop work cycle with accept connections or interrupt 77 // by system signal 78 for { 79 select { 80 case conn := <-listen: 81 go handleClient(conn) 82 case killSignal := <-interrupt: 83 stdlog.Println("Got signal:", killSignal) 84 stdlog.Println("Stoping listening on ", listener.Addr()) 85 listener.Close() 86 if killSignal == os.Interrupt { 87 return "Daemon was interrupted by system signal", nil 88 } 89 return "Daemon was killed", nil 90 } 91 } 92 } 93 94 // Accept a client connection and collect it in a channel 95 func acceptConnection(listener net.Listener, listen chan<- net.Conn) { 96 for { 97 conn, err := listener.Accept() 98 if err != nil { 99 continue 100 } 101 listen <- conn 102 } 103 } 104 105 func handleClient(client net.Conn) { 106 for { 107 buf := make([]byte, 4096) 108 numbytes, err := client.Read(buf) 109 if numbytes == 0 || err != nil { 110 return 111 } 112 client.Write(buf[:numbytes]) 113 } 114 } 115 116 func init() { 117 stdlog = log.New(os.Stdout, "", 0) 118 errlog = log.New(os.Stderr, "", 0) 119 } 120 121 func main() { 122 srv, err := daemon.New(name, description, daemon.SystemDaemon, dependencies...) 123 if err != nil { 124 errlog.Println("Error: ", err) 125 os.Exit(1) 126 } 127 service := &Service{srv} 128 status, err := service.Manage() 129 if err != nil { 130 errlog.Println(status, "\nError: ", err) 131 os.Exit(1) 132 } 133 fmt.Println(status) 134 135 }