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  }