Skip to content

Instantly share code, notes, and snippets.

@gmarik
Created April 1, 2014 21:24
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save gmarik/9923520 to your computer and use it in GitHub Desktop.
Save gmarik/9923520 to your computer and use it in GitHub Desktop.
package main
import (
"bufio"
"fmt"
"net"
)
type Client struct {
incoming chan string
outgoing chan string
reader *bufio.Reader
writer *bufio.Writer
leave chan bool
}
func (client *Client) Read() {
for {
line, err := client.reader.ReadString('\n')
if nil != err {
fmt.Println("Read", err)
break
}
client.incoming <- line
}
client.leave <- true
}
func (client *Client) Write() {
for data := range client.outgoing {
_, err := client.writer.WriteString(data)
if nil != err {
fmt.Println("Write", err)
break
}
client.writer.Flush()
}
fmt.Println("Exit Write")
client.leave <- true
}
func (client *Client) Listen() {
go client.Read()
go client.Write()
}
func NewClient(connection net.Conn) *Client {
writer := bufio.NewWriter(connection)
reader := bufio.NewReader(connection)
client := &Client{
leave: make(chan bool),
incoming: make(chan string),
outgoing: make(chan string),
reader: reader,
writer: writer,
}
return client
}
type ChatRoom struct {
clients []*Client
joins chan net.Conn
leaves chan *Client
incoming chan string
outgoing chan string
}
func (chatRoom *ChatRoom) Broadcast(data string) {
for _, client := range chatRoom.clients {
client.outgoing <- data
}
}
func (chatRoom *ChatRoom) Join(connection net.Conn) *Client {
client := NewClient(connection)
client.Listen()
chatRoom.clients = append(chatRoom.clients, client)
go func() {
for {
chatRoom.incoming <- <-client.incoming
}
}()
go func() { <-client.leave; chatRoom.leaves <- client }()
return client
}
// func (c *ChatRoom) Leave(client *Client) {
// c.leaves <- client
// }
func (chatRoom *ChatRoom) Listen() {
go func() {
for {
select {
case data := <-chatRoom.incoming:
chatRoom.Broadcast(data)
case conn := <-chatRoom.joins:
chatRoom.Join(conn)
fmt.Println("Client joined")
case <-chatRoom.leaves:
fmt.Println("Client left")
// chatRoom.Join(conn)
}
}
}()
}
func NewChatRoom() *ChatRoom {
chatRoom := &ChatRoom{
clients: make([]*Client, 0),
joins: make(chan net.Conn),
leaves: make(chan bool),
incoming: make(chan string),
outgoing: make(chan string),
}
chatRoom.Listen()
return chatRoom
}
func main() {
chatRoom := NewChatRoom()
listener, _ := net.Listen("tcp", ":6666")
for {
conn, _ := listener.Accept()
chatRoom.joins <- conn
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment