diff options
author | Nat Lasseter <user@4574.co.uk> | 2019-05-30 10:54:14 +0100 |
---|---|---|
committer | Nat Lasseter <user@4574.co.uk> | 2019-05-30 10:54:14 +0100 |
commit | 5caeb374c1652a4e871599c1e584d6c8f190714f (patch) | |
tree | 07004fa76a17f921097a2df48d4b36ada373dd2c | |
parent | 4269454497980738f61d02fed77ba6c05467c871 (diff) |
-rw-r--r-- | becomings/chat.go | 77 |
1 files changed, 77 insertions, 0 deletions
diff --git a/becomings/chat.go b/becomings/chat.go new file mode 100644 index 0000000..a531b97 --- /dev/null +++ b/becomings/chat.go @@ -0,0 +1,77 @@ +package main + +import ( + "fmt" + "github.com/grafov/bcast" + "net" + "os" +) + +const ( + LISTEN = "localhost:3334" +) + +type becoming struct { + Clients *bcast.Group +} + +func (b *becoming) Become() { + b.Clients = bcast.NewGroup() + go b.Clients.Broadcast(0) + + l, err := net.Listen("tcp", LISTEN) + if err != nil { + fmt.Println("Error listening: ", err.Error()) + os.Exit(1) + } + defer l.Close() + + for { + conn, err := l.Accept() + if err != nil { + fmt.Println("Error accepting: ", err.Error()) + } else { + go newClient(conn, b) + } + } +} + +func clientReader(conn net.Conn, ch chan []byte) { + buf := make([]byte, 256) + for { + _, err := conn.Read(buf) + if err != nil { + fmt.Println("Error reading: ", err.Error()) + return + } + ch <- buf + } +} + +func busReader(member *bcast.Member, ch chan []byte) { + for { + ch <- member.Recv().([]byte) + } +} + +func newClient(conn net.Conn, b *becoming) { + defer conn.Close() + member := b.Clients.Join() + defer b.Clients.Leave(member) + + in := make(chan []byte) + out := make(chan []byte) + go clientReader(conn, in) + go busReader(member, out) + + for { + select { + case msg := <-in: + member.Send(msg) + case msg := <-out: + conn.Write(msg) + } + } +} + +var Become becoming |