Tick server implemented in Go and Hare.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

87 lines
1.4 KiB

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)
}
}
}