diff options
| author | bt <bt@rctt.net> | 2026-03-08 01:19:47 +0100 |
|---|---|---|
| committer | bt <bt@rctt.net> | 2026-03-08 01:19:47 +0100 |
| commit | 18ca93effe37754b6642462325df02be37eb75ae (patch) | |
| tree | 3f6cc52aac2455110ef9a70ff3f45c8fe031a92d | |
| parent | 782394e769af6d89a6bc0656af1e4663c30844d6 (diff) | |
| download | solec-18ca93effe37754b6642462325df02be37eb75ae.tar.gz solec-18ca93effe37754b6642462325df02be37eb75ae.zip | |
Ping and pong
| -rw-r--r-- | PROTOCOL.md | 1 | ||||
| -rw-r--r-- | cmd/client/main.go | 20 | ||||
| -rw-r--r-- | cmd/daemon/main.go | 6 | ||||
| -rw-r--r-- | core/data.go | 76 | ||||
| -rw-r--r-- | core/network.go | 54 |
5 files changed, 113 insertions, 44 deletions
diff --git a/PROTOCOL.md b/PROTOCOL.md index 6686036..b481a0e 100644 --- a/PROTOCOL.md +++ b/PROTOCOL.md @@ -12,6 +12,7 @@ Every packet starts with `uint8` denoting type of the rest of remaining data. | 0x01 | Handshake | | 0x02 | Ping | | 0x03 | Pong | +| 0x04 | Message | | 0xFF | Test | ## Events diff --git a/cmd/client/main.go b/cmd/client/main.go index 244e543..a229632 100644 --- a/cmd/client/main.go +++ b/cmd/client/main.go @@ -4,6 +4,7 @@ import ( "flag" "log" "net" + "time" "git.sr.ht/~rctt/solecd/core" ) @@ -18,16 +19,21 @@ func main() { conn, err := d.Dial("tcp", serverAddr) if err != nil { - log.Fatalf("cannot dial", err) + log.Fatal("cannot dial: ", err) } defer conn.Close() - for { - d, err := core.Read(conn) - if err != nil { - log.Fatalf("cannot read data: %v", err) - } + go ping(conn) + if err := core.Loop(conn); err != nil { + log.Fatal("event loop error ", err) + } +} - log.Print(d) +func ping(conn net.Conn) { + for { + log.Print("ping") + p := core.Ping{} + core.Send(conn, core.TypePing, p) + time.Sleep(time.Second) } } diff --git a/cmd/daemon/main.go b/cmd/daemon/main.go index ad503c5..b344caf 100644 --- a/cmd/daemon/main.go +++ b/cmd/daemon/main.go @@ -45,9 +45,7 @@ func handle(conn net.Conn) { return } - test := core.Test{Message: "solec kujawski jest zajebisty"} - if err := core.Send(conn, core.TypeTest, test); err != nil { - log.Print("cannot send test message ", err) - return + if err := core.Loop(conn); err != nil { + log.Fatal("event loop error ", err) } } diff --git a/core/data.go b/core/data.go index 7ccc4f9..ddf1db8 100644 --- a/core/data.go +++ b/core/data.go @@ -5,6 +5,7 @@ import ( "fmt" "io" "strings" + "time" ) type Marshaler interface { @@ -21,63 +22,72 @@ const ( TypeTest = 0xFF ) +func ReadDataType(r io.Reader) (DataType, error) { + var data uint8 + if err := read(r, &data); err != nil { + return TypeUnknown, err + } + + dType := DataType(data) + + return dType, nil +} + type Handshake struct { Version uint8 } -func (h Handshake) Marshal() []any { - return []any{h.Version} +func (t Handshake) Marshal() []any { + return []any{t.Version} } func ReadHandshake(r io.Reader) (Handshake, error) { - var d Handshake - err := read(r, &d.Version) - return d, err + var t Handshake + err := read(r, &t.Version) + return t, err } type Test struct { Message string } -func ReadTest(r io.Reader) (Test, error) { - var d Test - err := readString(r, &d.Message) - return d, err +func (t Test) Marshal() []any { + return []any{append([]byte(t.Message), 0x0)} } -func (h Test) Marshal() []any { - return []any{append([]byte(h.Message), 0x0)} +func ReadTest(r io.Reader) (Test, error) { + var t Test + err := readString(r, &t.Message) + return t, err } -func Read(r io.Reader) (any, error) { - dType, err := ReadDataType(r) - if err != nil { - return nil, fmt.Errorf("cannot read data type", err) - } +type Ping struct{} - switch dType { - case TypeUnknown: - return nil, fmt.Errorf("cannot read data type 0x00 (TypeUnknown)") - case TypeHandshake: - return ReadHandshake(r) - case TypeTest: - return ReadTest(r) - default: - return nil, fmt.Errorf("unsupported type: %v", dType) - } +func (t Ping) Marshal() []any { + return []any{} } -func ReadDataType(r io.Reader) (DataType, error) { - var data uint8 - if err := read(r, &data); err != nil { - return TypeUnknown, err - } +type Pong struct { + Timestamp time.Time +} - dType := DataType(data) +func (t Pong) Marshal() []any { + return []any{uint64(t.Timestamp.Unix())} +} - return dType, nil +func ReadPong(r io.Reader) (Pong, error) { + var ( + t Pong + timestamp uint64 + ) + + err := read(r, ×tamp) + t.Timestamp = time.Unix(int64(timestamp), 0) + return t, err } +// + func readString(r io.Reader, ptr *string) error { var ( sb strings.Builder diff --git a/core/network.go b/core/network.go index 50c398f..c662981 100644 --- a/core/network.go +++ b/core/network.go @@ -3,7 +3,10 @@ package core import ( "encoding/binary" "fmt" + "io" + "log" "net" + "time" ) func Send(conn net.Conn, dataType DataType, data Marshaler) error { @@ -19,3 +22,54 @@ func Send(conn net.Conn, dataType DataType, data Marshaler) error { return nil } + +func Read(r io.Reader) (any, error) { + dType, err := ReadDataType(r) + if err != nil { + return nil, fmt.Errorf("cannot read data type", err) + } + + switch dType { + case TypeUnknown: + return nil, fmt.Errorf("cannot read data type 0x00 (TypeUnknown)") + case TypeHandshake: + return ReadHandshake(r) + case TypePing: + return Ping{}, nil + case TypePong: + return ReadPong(r) + case TypeTest: + return ReadTest(r) + default: + return nil, fmt.Errorf("unsupported type: %v", dType) + } +} + +func Loop(conn net.Conn) error { + for { + d, err := Read(conn) + if err != nil { + return fmt.Errorf("cannot read data: %v", err) + } + + if err := handleEvent(d, conn); err != nil { + return fmt.Errorf("cannot handle event: %v", err) + } + } +} + +func handleEvent(data any, conn net.Conn) error { + switch v := data.(type) { + case Handshake: + case Ping: + log.Print("received ping") + return Send(conn, TypePong, Pong{time.Now()}) + case Pong: + log.Print("received pong ", v.Timestamp) + case Test: + default: + return fmt.Errorf("unknown type") + } + + return nil +} |
