Alexander Avery
9 months ago
commit
1aae6b02d5
1 changed files with 86 additions and 0 deletions
@ -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) |
|||
} |
|||
} |
|||
} |
Loading…
Reference in new issue