commit 1aae6b02d5a6a09856889c3320aa945c231f0921 Author: Alexander Avery Date: Sun Mar 10 17:45:10 2024 -0400 add Go tick server diff --git a/main.go b/main.go new file mode 100644 index 0000000..7f405b1 --- /dev/null +++ b/main.go @@ -0,0 +1,86 @@ +package main + +import ( + "bufio" + "io" + "log" + "net" + "time" +) + +// read all messages from client. +func read(rc io.ReadCloser, id int, msg chan<- string, done chan<- int) { + defer rc.Close() + + scanner := bufio.NewScanner(rc) + for scanner.Scan() { + msg <- scanner.Text() + } + + done <- id +} + +// write 'tick' message to all clients. +func write(conns []net.Conn) { + for _, c := range conns { + if c != nil { + io.WriteString(c, "tick\n") + } + } +} + +// add a client and read messages if there is room. +func addClient(conns []net.Conn, conn net.Conn, msg chan<- string, done chan<- int) []net.Conn { + for i, c := range conns { + if c == nil { + go read(conn, i, msg, done) + conns[i] = conn + return conns + } + } + + // reject the client if we are full + conn.Close() + return conns +} + +func main() { + conns := make([]net.Conn, 15) + + connC := make(chan net.Conn, 0) + msgC := make(chan string, 0) + doneC := make(chan int, 0) + + listener, err := net.Listen("tcp", ":8080") + if err != nil { + log.Fatalf("listening on :8080: %s", err.Error()) + } + + go func() { + for { + c, err := listener.Accept() + if err == nil { + connC <- c + } + } + }() + + ticker := time.NewTicker(time.Second) + + for { + select { + + case conn := <-connC: + conns = addClient(conns, conn, msgC, doneC) + + case id := <-doneC: + conns[id] = nil + + case msg := <-msgC: + log.Printf("client said: %s", msg) + + case <-ticker.C: + write(conns) + } + } +}