Instantly share code, notes, and snippets.

Embed
What would you like to do?
simple golang chat server
package main
import (
"bufio"
"net"
)
type Client struct {
incoming chan string
outgoing chan string
reader *bufio.Reader
writer *bufio.Writer
}
func (client *Client) Read() {
for {
line, _ := client.reader.ReadString('\n')
client.incoming <- line
}
}
func (client *Client) Write() {
for data := range client.outgoing {
client.writer.WriteString(data)
client.writer.Flush()
}
}
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{
incoming: make(chan string),
outgoing: make(chan string),
reader: reader,
writer: writer,
}
client.Listen()
return client
}
type ChatRoom struct {
clients []*Client
joins chan net.Conn
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 := NewClient(connection)
chatRoom.clients = append(chatRoom.clients, client)
go func() { for { chatRoom.incoming <- <-client.incoming } }()
}
func (chatRoom *ChatRoom) Listen() {
go func() {
for {
select {
case data := <-chatRoom.incoming:
chatRoom.Broadcast(data)
case conn := <-chatRoom.joins:
chatRoom.Join(conn)
}
}
}()
}
func NewChatRoom() *ChatRoom {
chatRoom := &ChatRoom{
clients: make([]*Client, 0),
joins: make(chan net.Conn),
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
}
}
@sigmonsays

This comment has been minimized.

Show comment
Hide comment
@sigmonsays

sigmonsays Oct 17, 2016

this code needs error checking and the ability to deal with clients who terminate their connection.

sigmonsays commented Oct 17, 2016

this code needs error checking and the ability to deal with clients who terminate their connection.

@JunYeol

This comment has been minimized.

Show comment
Hide comment
@JunYeol

JunYeol Oct 17, 2016

how can this program get terminal(shall) input?

JunYeol commented Oct 17, 2016

how can this program get terminal(shall) input?

@coolspeed

This comment has been minimized.

Show comment
Hide comment
@coolspeed

coolspeed Feb 12, 2017

I scratched a more complex one from this with basic error handlings:

https://github.com/coolspeed/century

coolspeed commented Feb 12, 2017

I scratched a more complex one from this with basic error handlings:

https://github.com/coolspeed/century

@continuum-swaresh-sankpal

This comment has been minimized.

Show comment
Hide comment
@continuum-swaresh-sankpal

continuum-swaresh-sankpal Aug 9, 2017

how to send message to particular client rather than broadcasting the message?

continuum-swaresh-sankpal commented Aug 9, 2017

how to send message to particular client rather than broadcasting the message?

@FlowerWrong

This comment has been minimized.

Show comment
Hide comment
@FlowerWrong

FlowerWrong commented Jan 16, 2018

beautiful

@Stormcore

This comment has been minimized.

Show comment
Hide comment
@Stormcore

Stormcore Jan 22, 2018

@continuum-swaresh-sankpal

func (client *Client) Write() {
for data := range client.outgoing {
client.writer.WriteString(data)
client.writer.Flush()
}
}

Stormcore commented Jan 22, 2018

@continuum-swaresh-sankpal

func (client *Client) Write() {
for data := range client.outgoing {
client.writer.WriteString(data)
client.writer.Flush()
}
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment