From 950aeda87ee662a12c6e0a587ebc2a6c87dc1404 Mon Sep 17 00:00:00 2001 From: Jordan Orelli Date: Sun, 25 Oct 2020 16:21:52 +0000 Subject: [PATCH] connection closing --- client.go | 36 +++++++++++++++++++++++++++--------- ui.go | 18 +++++++++++++++--- 2 files changed, 42 insertions(+), 12 deletions(-) diff --git a/client.go b/client.go index 0831a8a..426ddf4 100644 --- a/client.go +++ b/client.go @@ -1,6 +1,7 @@ package main import ( + "context" "fmt" "net/url" "strings" @@ -16,7 +17,7 @@ type client struct { port int } -func (c *client) run() { +func (c *client) run(ctx context.Context) { dialer := websocket.Dialer{ HandshakeTimeout: 3 * time.Second, ReadBufferSize: 32 * 1024, @@ -41,15 +42,32 @@ func (c *client) run() { c.Debug("dial response header: %s = %s", k, strings.Join(vals, ",")) } + tick := time.NewTicker(time.Second) + defer tick.Stop() + for { - w, err := conn.NextWriter(websocket.TextMessage) - if err != nil { - c.Error("unable to get a websocket frame writer: %v", err) - break - } + select { + case <-tick.C: + w, err := conn.NextWriter(websocket.TextMessage) + if err != nil { + c.Error("unable to get a websocket frame writer: %v", err) + break + } - w.Write([]byte("hey")) - w.Close() - time.Sleep(time.Second) + w.Write([]byte("hey")) + w.Close() + case <-ctx.Done(): + c.Info("parent context done, sending close message") + msg := websocket.FormatCloseMessage(websocket.CloseNormalClosure, "") + if err := conn.WriteMessage(websocket.CloseMessage, msg); err != nil { + c.Error("failed to write close message: %v", err) + } + c.Info("closing connection") + if err := conn.Close(); err != nil { + c.Error("failed to close connection: %v", err) + } + c.Info("connection closed") + return + } } } diff --git a/ui.go b/ui.go index 494c63f..d54f947 100644 --- a/ui.go +++ b/ui.go @@ -1,6 +1,9 @@ package main import ( + "context" + "time" + "github.com/gdamore/tcell/v2" "github.com/jordanorelli/belt-mud/internal/exit" "github.com/jordanorelli/blammo" @@ -11,15 +14,25 @@ type ui struct { *blammo.Log screen tcell.Screen mode uiMode + client *client } func (ui *ui) run() { - c := client{ + ui.client = &client{ Log: ui.Child("client"), host: "127.0.0.1", port: 12805, } - go c.run() + ctx := context.Background() + + ctx, cancel := context.WithCancel(ctx) + defer func() { + ui.Debug("canceling client context") + cancel() + time.Sleep(time.Second) + }() + + go ui.client.run(ctx) screen, err := tcell.NewScreen() if err != nil { @@ -90,7 +103,6 @@ func (ui *ui) menu() { } ui.mode.HandleEvent(e) - ui.screen.Clear() ui.mode.draw(ui) ui.screen.Show()