func (s *Server) ServeOne(id string, conn io.ReadWriteCloser) { log.Printf("New client: %v", runtime.NumGoroutine()) //defer log.Printf("Client %q disconnected", id) xport := fatchan.New(conn, nil) login := make(chan Login) _, err := xport.ToChan(login) if err != nil { return } client := <-login defer close(client.Recv) // See https://github.com/kylelemons/fatchan/issues/3 // This is a workaround, the server sends something first. client.Recv <- Message{Type: MESSAGE_TYPE_ACKNOWLEDGE} switch client.Type { case CLIENT_TYPE_JOB: s.ServeJobRequest(client) case CLIENT_TYPE_WORKER: s.ServeWorker(client) default: log.Panicf("Bad client type! %v", client.Type) } }
// Connect to `addr` by sshing through `via` (if specified), telling the server // that we are a `client_type` and passing an approprite Login struct func Connect(addr, via string, client_type ClientType) (io.ReadWriteCloser, Login) { var conn io.ReadWriteCloser var err error if via != "" { conn, err = SafeDial(via, addr) } else { conn, err = net.Dial("tcp", addr) } if err != nil { log.Fatalf("Connect(%q, %q): %s", addr, via, err) } xport := fatchan.New(conn, nil) login := make(chan Login) _, err = xport.FromChan(login) if err != nil { log.Fatalf("Connect(%q, %q): %s", addr, via, err) } defer close(login) me := Login{ Type: client_type, Send: make(chan Message), Recv: make(chan Message), } login <- me return conn, me }
func serve(id string, client io.ReadWriteCloser) { log.Printf("Client %q connected", id) defer log.Printf("Client %q disconnected", id) xport := fatchan.New(client, nil) login := make(chan Handshake) xport.ToChan(login) user := <-login log.Printf("Client %q registered as %q", id, user.User) if !addUser(user.User, user.Recv) { user.Recv <- packet.Packet{ Chat: &packet.Chat{ User: "******", Message: "That username is already taken.", }, } close(user.Recv) return } defer delUser(user.Recv) defer close(user.Recv) player := serverpkg.NewPlayer(id, user.User, user.Recv) defer player.Disconnected() for msg := range user.Send { if !serverpkg.Dispatch(player, msg) { return } } }
func client(username string, server io.ReadWriteCloser) { log.Printf("Connected to server") defer log.Printf("Server disconnected") xport := fatchan.New(server, nil) login := make(chan Handshake) xport.FromChan(login) defer close(login) me := Handshake{ User: username, Send: make(chan packet.Packet), Recv: make(chan packet.Packet), } login <- me in := bufio.NewReader(os.Stdin) clientpkg.Network = me.Send go func() { defer close(me.Send) for { line, err := in.ReadString('\n') if err == io.EOF { return } if err != nil { log.Fatalf("readline(): %s", err) } me.Send <- packet.Packet{ Chat: &packet.Chat{ Message: line, }, } } }() go func() { for msg := range me.Recv { clientpkg.Handle(msg) } clientpkg.Disconnected() }() clientpkg.Main() }
func serve(id string, client io.ReadWriteCloser) { log.Printf("Client %q connected", id) defer log.Printf("Client %q disconnected", id) xport := fatchan.New(client, nil) login := make(chan LogIn) xport.ToChan(login) user := <-login log.Printf("Client %q registered as %q", id, user.User) addUser(user.User, user.Recv) defer delUser(user.Recv) defer close(user.Recv) for msg := range user.Send { msg.User = user.User log.Printf("<%s> %s", msg.User, msg.Message) go sendAll(msg) } }
func client(username string, user io.Reader, server io.ReadWriteCloser) { log.Printf("Connected to server") defer log.Printf("Server disconnected") xport := fatchan.New(server, nil) login := make(chan LogIn) xport.FromChan(login) defer close(login) me := LogIn{ User: username, Send: make(chan Message), Recv: make(chan Message), } login <- me go func() { defer close(me.Send) br := bufio.NewReader(user) for { line, err := br.ReadString('\n') if err == io.EOF { log.Printf("Disconnecting...") return } if err != nil { log.Printf("readline(): %s", err) return } me.Send <- Message{ Message: line, } } }() for msg := range me.Recv { log.Printf("<%s> %s", msg.User, msg.Message) } }