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