Skip to content

Instantly share code, notes, and snippets.

@tanema
Created October 3, 2013 16:47
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tanema/6813023 to your computer and use it in GitHub Desktop.
Save tanema/6813023 to your computer and use it in GitHub Desktop.
distributed chat client made for a golang hack night, it can both send and receive messages
package main
import (
"fmt"
"flag"
"net"
"bufio"
"os"
"time"
"strconv"
"strings"
)
var connection_list []net.Conn
var seen = map[string]bool{}
func handlePeer(conn net.Conn, send chan string){
println("Peer connected")
connection_list = append(connection_list, conn)
defer func(){
//TODO remove from connections
conn.Close()
}()
for {
line, err := bufio.NewReader(conn).ReadString('\n')
if err != nil {
println("disconnecting peer")
return
}
send <- line
}
}
func handleBroadcast(send chan string) {
for s := range send {
bits := strings.SplitN(s, " ", 3)
if len(bits) != 3 {
fmt.Printf("Error: invalid line: %v\n", bits)
continue
}
if seen[bits[0]] {
continue
}
fmt.Printf("%s: %s", bits[1], bits[2])
seen[bits[0]] = true
for _, conn := range connection_list {
_, err := conn.Write([]byte(s + "\n"))
if err != nil {
fmt.Printf("error writing out to connection: %s \n", err)
}
}
}
}
func listen(listen_host string, send chan string) {
fmt.Printf("listening on %s \n", listen_host)
listen, _ := net.Listen("tcp", listen_host)
go handleBroadcast(send)
for {
conn, err := listen.Accept()
if err != nil {
continue
}
go handlePeer(conn, send)
}
}
func main() {
var peer, host, ident string
flag.StringVar(&host, "h", "localhost:4569", "Your localhost that you are listening on")
flag.StringVar(&peer, "p", "", "A peer to initially connect to")
flag.StringVar(&ident, "i", "anon", "identity on the chat")
flag.Parse()
send := make(chan string)
if peer != "" {
fmt.Printf("connecting to %s \n", peer)
say, _ := net.Dial("tcp", peer)
go handlePeer(say, send)
}
go listen(host, send)
scanner := bufio.NewScanner(os.Stdin)
for scanner.Scan() {
send <- strconv.FormatInt(time.Now().Unix(), 10) + " " + ident + " " + scanner.Text() + "\n"
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment