summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorbt <bt@rctt.net>2026-04-10 20:07:48 +0200
committerbt <bt@rctt.net>2026-04-10 20:07:48 +0200
commit74763b4b327f620c933f78b2a65d8704e8aa8e12 (patch)
treeff7f3ab92bf369e2d1ff613705bca00c1337decb
parent75504a81885db55a3f5f9041dcda6b9d2ef421b2 (diff)
downloadsolec-0.1.0.tar.gz
solec-0.1.0.zip
[client] Move client implementation to separate packagev0.1.0
-rw-r--r--client/client.go80
-rw-r--r--cmd/client/main.go74
-rw-r--r--docs/rfc.html10
-rw-r--r--docs/rfc.txt4
4 files changed, 106 insertions, 62 deletions
diff --git a/client/client.go b/client/client.go
new file mode 100644
index 0000000..a294bca
--- /dev/null
+++ b/client/client.go
@@ -0,0 +1,80 @@
+package client
+
+import (
+ "net"
+
+ "git.rctt.net/solec/core"
+)
+
+type Handler interface {
+ HandleMessage(msg core.Message)
+ HandleError(err error)
+}
+
+type Client struct {
+ h Handler
+ conn net.Conn
+
+ addr string
+ uname string
+ pass string
+}
+
+func NewClient(handler Handler, addr, uname, pass string) *Client {
+ return &Client{
+ h: handler,
+ addr: addr,
+ uname: uname,
+ pass: pass,
+ }
+}
+
+func (c *Client) Connect() error {
+ var err error
+ c.conn, err = net.Dial("tcp", c.addr)
+ if err != nil {
+ return err
+ }
+ defer c.conn.Close()
+
+ hs := core.Handshake{0, 1}
+ if err := core.Send(c.conn, hs); err != nil {
+ return err
+ }
+
+ auth := core.Auth{c.uname, c.pass}
+ if err := core.Send(c.conn, auth); err != nil {
+ return err
+ }
+
+ c.read()
+ return nil
+}
+
+func (c *Client) SendMessage(target, content string) error {
+ msg := core.Message{
+ Source: c.uname + "@" + c.addr,
+ Target: target,
+ Content: content,
+ }
+
+ return core.Send(c.conn, msg)
+}
+
+func (c *Client) read() {
+ for {
+ payload, err := core.Read(c.conn)
+ if err != nil {
+ c.h.HandleError(err)
+ }
+
+ c.handlePayload(payload)
+ }
+}
+
+func (c *Client) handlePayload(payload any) {
+ switch v := payload.(type) {
+ case core.Message:
+ c.h.HandleMessage(v)
+ }
+}
diff --git a/cmd/client/main.go b/cmd/client/main.go
index c362247..defcc17 100644
--- a/cmd/client/main.go
+++ b/cmd/client/main.go
@@ -2,12 +2,11 @@ package main
import (
"flag"
- "fmt"
"log"
"net"
"strings"
- "time"
+ "git.rctt.net/solec/client"
"git.rctt.net/solec/core"
"git.rctt.net/solec/prompt"
)
@@ -16,8 +15,19 @@ var (
serverAddr string
user string
conn net.Conn
+ c *client.Client
)
+type Handler struct{}
+
+func (h *Handler) HandleMessage(msg core.Message) {
+ log.Println("received message", msg.Source, "->", msg.Target, msg.Content)
+}
+
+func (h *Handler) HandleError(err error) {
+ log.Println("client error:", err)
+}
+
func main() {
prompt.Commands["send"] = sendMessage
@@ -25,67 +35,21 @@ func main() {
flag.StringVar(&user, "u", "user", "username")
flag.Parse()
- var (
- d net.Dialer
- err error
- )
-
log.Println("connecting to " + serverAddr + " as " + user)
- conn, err = d.Dial("tcp", serverAddr)
- if err != nil {
- log.Fatal("cannot dial: ", err)
- }
- defer conn.Close()
-
- hs := core.Handshake{0, 1}
- if err := core.Send(conn, hs); err != nil {
- panic(err)
- }
-
- auth := core.Auth{user, "valid"}
- if err := core.Send(conn, auth); err != nil {
- panic(err)
- }
+ c = client.NewClient(&Handler{}, serverAddr, user, "valid")
go prompt.Read()
- read(conn)
-}
-
-func read(conn net.Conn) {
- for {
- payload, err := core.Read(conn)
- if err != nil {
- panic(err)
- }
-
- handlePayload(conn, payload)
- }
-}
-
-func handlePayload(conn net.Conn, payload any) {
- switch v := payload.(type) {
- case core.Message:
- handleMessage(conn, v)
- default:
- fmt.Println(payload)
+ if err := c.Connect(); err != nil {
+ log.Fatal(err)
+ return
}
}
-func handleMessage(conn net.Conn, msg core.Message) {
- log.Println("received message", msg.Source, "->", msg.Target, msg.Content)
-}
-
func sendMessage(args []string) {
- msg := core.Message{
- Source: user,
- Target: args[0],
- Timestamp: time.Now(),
- Content: strings.Join(args[1:], " "),
- }
-
- if err := core.Send(conn, msg); err != nil {
- panic(err)
+ err := c.SendMessage(args[0], strings.Join(args[1:], " "))
+ if err != nil {
+ log.Println("cannot send message:", err)
}
}
diff --git a/docs/rfc.html b/docs/rfc.html
index 30f5bb7..aaa92ce 100644
--- a/docs/rfc.html
+++ b/docs/rfc.html
@@ -1216,11 +1216,11 @@ li > p:last-of-type:only-child {
<thead><tr>
<td class="left">Internet-Draft</td>
<td class="center">SOLEC</td>
-<td class="right">March 2026</td>
+<td class="right">April 2026</td>
</tr></thead>
<tfoot><tr>
<td class="left">bt</td>
-<td class="center">Expires 2 October 2026</td>
+<td class="center">Expires 12 October 2026</td>
<td class="right">[Page]</td>
</tr></tfoot>
</table>
@@ -1233,12 +1233,12 @@ li > p:last-of-type:only-child {
<dd class="internet-draft">SOLEC</dd>
<dt class="label-published">Published:</dt>
<dd class="published">
-<time datetime="2026-03-31" class="published">31 March 2026</time>
+<time datetime="2026-04-10" class="published">10 April 2026</time>
</dd>
<dt class="label-intended-status">Intended Status:</dt>
<dd class="intended-status">Experimental</dd>
<dt class="label-expires">Expires:</dt>
-<dd class="expires"><time datetime="2026-10-02">2 October 2026</time></dd>
+<dd class="expires"><time datetime="2026-10-12">12 October 2026</time></dd>
<dt class="label-authors">Author:</dt>
<dd class="authors">
<div class="author">
@@ -1274,7 +1274,7 @@ SOLEC system.<a href="#section-abstract-1" class="pilcrow">¶</a></p>
time. It is inappropriate to use Internet-Drafts as reference
material or to cite them other than as "work in progress."<a href="#section-boilerplate.1-3" class="pilcrow">¶</a></p>
<p id="section-boilerplate.1-4">
- This Internet-Draft will expire on 2 October 2026.<a href="#section-boilerplate.1-4" class="pilcrow">¶</a></p>
+ This Internet-Draft will expire on 12 October 2026.<a href="#section-boilerplate.1-4" class="pilcrow">¶</a></p>
</section>
</div>
<div id="copyright">
diff --git a/docs/rfc.txt b/docs/rfc.txt
index 2029e6f..a19de19 100644
--- a/docs/rfc.txt
+++ b/docs/rfc.txt
@@ -1,7 +1,7 @@
SOLEC Working Group bt, Ed.
Internet-Draft RCTT.net
-Intended status: Experimental 31 March 2026
-Expires: 2 October 2026
+Intended status: Experimental 10 April 2026
+Expires: 12 October 2026
System of Lightweight Electronic Communication