1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
|
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", "")
ws, err := db.SelectDict(context.Background(), q, 10)
if err != nil {
slog.Error("Error selecting", "error", err)
return
}
for _, w := range ws {
fmt.Fprintf(conn, "%s\n%s\n\n", w.Word, w.Line)
}
}
|