From ea26916be0ea693b6aefc46f3eeb62e44b8d7cb0 Mon Sep 17 00:00:00 2001 From: "Gabriel A. Giovanini" Date: Fri, 19 Apr 2024 19:33:10 +0200 Subject: feat: Add barebones tcp server --- cmd/dict/main.go | 2 ++ cmd/server/server.go | 96 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 98 insertions(+) create mode 100644 cmd/server/server.go (limited to 'cmd') diff --git a/cmd/dict/main.go b/cmd/dict/main.go index 09e9412..5bd6096 100644 --- a/cmd/dict/main.go +++ b/cmd/dict/main.go @@ -7,6 +7,7 @@ import ( "github.com/urfave/cli/v2" "git.gabrielgio.me/dict/cmd/importer" + "git.gabrielgio.me/dict/cmd/server" "git.gabrielgio.me/dict/cmd/ui" ) @@ -17,6 +18,7 @@ func main() { Commands: []*cli.Command{ importer.ImportCommand, ui.UICommand, + server.ServeCommand, }, } diff --git a/cmd/server/server.go b/cmd/server/server.go new file mode 100644 index 0000000..a0de547 --- /dev/null +++ b/cmd/server/server.go @@ -0,0 +1,96 @@ +package server + +import ( + "context" + "fmt" + "io" + "log/slog" + "net" + "strings" + + "git.gabrielgio.me/dict/db" + "github.com/urfave/cli/v2" +) + +var ServeCommand = &cli.Command{ + Name: "serve", + Usage: "Start a simple tcp server to ansower queries", + Flags: []cli.Flag{ + &cli.StringFlag{ + Name: "addr", + Value: "/tmp/dict.sock", + Usage: "Address", + }, + &cli.StringFlag{ + Name: "database", + Value: "main.dict", + Usage: "Dictionary database location", + }, + }, + Action: func(cCtx *cli.Context) error { + addr := cCtx.String("addr") + database := cCtx.String("database") + return Server(context.Background(), addr, database) + }, +} + +func Server(ctx context.Context, addr, database string) error { + // Listen for incoming connections on port 8080 + db, err := db.Open(database) + if err != nil { + return fmt.Errorf("Error openning datbase:%w", err) + } + + ln, err := net.Listen("unix", addr) + if err != nil { + return err + } + + defer ln.Close() + + // Accept incoming connections and handle them + for { + conn, err := ln.Accept() + if err != nil { + slog.Error("Error accepting conn", "error", err) + continue + } + + slog.Info("Connection accepeted") + go handleConnection(conn, db) + } +} + +func handleConnection(conn net.Conn, db *db.DB) { + defer conn.Close() + + // Read incoming data + buf := make([]byte, 0, 4096) // big buffer + tmp := make([]byte, 256) // using small tmo buffer for demonstrating + for { + n, err := conn.Read(tmp) + if err != nil { + if err != io.EOF { + slog.Error("Error reading conn", "error", err) + return + } + break + } + buf = append(buf, tmp[:n]...) + + } + + q := strings.ReplaceAll(string(buf), "\n", "") + + slog.Info("Query", "query", q) + ws, err := db.SelectDict(context.Background(), q, 10) + if err != nil { + slog.Error("Error selecting", "error", err) + return + } + + slog.Info("Count", "q", len(ws)) + for _, w := range ws { + fmt.Fprintf(conn, "%s\n%s\n\n", w.Word, w.Line) + } +} -- cgit v1.2.3