summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorbt <bt@rctt.net>2026-03-08 01:19:47 +0100
committerbt <bt@rctt.net>2026-03-08 01:19:47 +0100
commit18ca93effe37754b6642462325df02be37eb75ae (patch)
tree3f6cc52aac2455110ef9a70ff3f45c8fe031a92d
parent782394e769af6d89a6bc0656af1e4663c30844d6 (diff)
downloadsolec-18ca93effe37754b6642462325df02be37eb75ae.tar.gz
solec-18ca93effe37754b6642462325df02be37eb75ae.zip
Ping and pong
-rw-r--r--PROTOCOL.md1
-rw-r--r--cmd/client/main.go20
-rw-r--r--cmd/daemon/main.go6
-rw-r--r--core/data.go76
-rw-r--r--core/network.go54
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, &timestamp)
+ 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
+}