Created
October 14, 2025 08:23
-
-
Save Kjue/fed81f79e84c0cfd28219bc46bb8a133 to your computer and use it in GitHub Desktop.
Go version of the server with socket CLI.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| package main | |
| import ( | |
| "encoding/json" | |
| "fmt" | |
| "io" | |
| "log" | |
| "net" | |
| "os" | |
| "os/signal" | |
| "path/filepath" | |
| "syscall" | |
| ) | |
| type CommandPayload struct { | |
| Command string `json:"command"` | |
| Args []string `json:"args"` | |
| } | |
| func main() { | |
| socketPath := getSocketPath() | |
| args := os.Args[1:] | |
| var command string | |
| if len(args) > 0 { | |
| command = args[0] | |
| } | |
| // Probe the socket to see if a server is running. | |
| conn, err := net.Dial("unix", socketPath) | |
| if err != nil { | |
| opErr, ok := err.(*net.OpError) | |
| if !ok { | |
| log.Fatalf("An unexpected error occurred while probing the socket: %v", err) | |
| } | |
| if opErr.Err == syscall.ECONNREFUSED || os.IsNotExist(opErr.Err) { | |
| if command != "" { | |
| log.Fatal("β Error: Server is not running. Cannot execute command.") | |
| } else { | |
| fmt.Println("β No active server found. Starting a new one...") | |
| os.Remove(socketPath) | |
| startServerProcess(socketPath) | |
| } | |
| } else { | |
| log.Fatalf("An unexpected network error occurred while probing the socket: %v", err) | |
| } | |
| return | |
| } | |
| // If we reach here, err was nil, so the server is ALREADY RUNNING. | |
| conn.Close() // We're done with the probe. | |
| if command != "" { | |
| runCommand(socketPath, command, args[1:]) | |
| } else { | |
| showHelpAndExit(true) | |
| } | |
| } | |
| func startServerProcess(socketPath string) { | |
| fmt.Printf("π Server process with PID: %d is starting.\n", os.Getpid()) | |
| listener, err := net.Listen("unix", socketPath) | |
| if err != nil { | |
| log.Fatalf("Failed to bind to socket: %v", err) | |
| } | |
| // Set up graceful shutdown. | |
| sigChan := make(chan os.Signal, 1) | |
| signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM) | |
| go func() { | |
| <-sigChan | |
| fmt.Println("\n[Server] Shutting down, removing socket...") | |
| listener.Close() | |
| os.Remove(socketPath) | |
| os.Exit(0) | |
| }() | |
| fmt.Println(" β Application logic is running. Listening for commands...") | |
| for { | |
| conn, err := listener.Accept() | |
| if err != nil { | |
| break | |
| } | |
| go handleClient(conn) | |
| } | |
| } | |
| func handleClient(conn net.Conn) { | |
| defer conn.Close() | |
| decoder := json.NewDecoder(conn) | |
| var payload CommandPayload | |
| if err := decoder.Decode(&payload); err != nil { | |
| fmt.Fprintf(conn, "Error decoding command: %v", err) | |
| return | |
| } | |
| fmt.Printf("[Server] Received command: \"%s\" with args: %v\n", payload.Command, payload.Args) | |
| if payload.Command == "stop" { | |
| fmt.Fprint(conn, "β Server is shutting down...") | |
| p, _ := os.FindProcess(os.Getpid()) | |
| p.Signal(syscall.SIGTERM) | |
| return | |
| } | |
| response := handleCommand(payload) | |
| fmt.Fprint(conn, response) | |
| } | |
| func showHelpAndExit(isRunning bool) { | |
| if isRunning { | |
| fmt.Println("β Server is already running.") | |
| } | |
| fmt.Printf("\nUsage: %s <command> [arguments]\n\n", os.Args[0]) | |
| fmt.Println("Available commands:") | |
| fmt.Println(" status Check the status of the running server") | |
| fmt.Println(" create:org <name> Create a new organization") | |
| fmt.Println(" stop Stop the running server daemon") | |
| os.Exit(0) | |
| } | |
| func handleCommand(payload CommandPayload) string { | |
| switch payload.Command { | |
| case "status": | |
| status := map[string]interface{}{ | |
| "processPid": os.Getpid(), | |
| "status": "running", | |
| "startTime": "N/A in this demo", | |
| } | |
| jsonData, _ := json.MarshalIndent(status, "", " ") | |
| return string(jsonData) | |
| case "create:org": | |
| if len(payload.Args) < 1 { | |
| return "Error: Organization name is required." | |
| } | |
| return fmt.Sprintf("Organization \"%s\" created successfully.", payload.Args[0]) | |
| default: | |
| return fmt.Sprintf("Error: Unknown command \"%s\"", payload.Command) | |
| } | |
| } | |
| func getSocketPath() string { | |
| return filepath.Join(os.TempDir(), "go-app-daemon.sock") | |
| } | |
| func runCommand(socketPath, command string, args []string) { | |
| conn, err := net.Dial("unix", socketPath) | |
| if err != nil { | |
| log.Fatalf("β Error connecting to server to run command: %v", err) | |
| } | |
| defer conn.Close() | |
| payload := CommandPayload{Command: command, Args: args} | |
| encoder := json.NewEncoder(conn) | |
| if err := encoder.Encode(&payload); err != nil { | |
| log.Fatalf("Failed to send command to server: %v", err) | |
| } | |
| response, err := io.ReadAll(conn) | |
| if err != nil { | |
| log.Fatalf("Failed to read response from server: %v", err) | |
| } | |
| fmt.Println(string(response)) | |
| } |
Author
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Please see my blog post about this on dev.to.