//ircManager takes the connection to the IRC server and then coordinates the //communication between the irc server, and the active IRCClients func ircManager(ircConn irc.IRCConn, newClients chan *ircClient) { fmt.Println("*** Entering ircManager ***") defer fmt.Println("*** Leaving ircManager ***") var clients []*ircClient fromServer := make(chan irc.Message) fromClient := make(chan irc.Message) errChan := make(chan error) quitChan := make(chan bool) //Listen for incoming messages form server go ircServerListener(ircConn, fromServer, errChan, quitChan) for { select { case msg := <-fromServer: //Log it, log.Println(msg) //Repsond if it's a ping if len(msg) >= 4 && msg[0:4] == "PING" { var end string = msg[4:].String() ircConn.Write(irc.NewMessage("PONG" + end)) //break } //...and send it to all clients for k := 0; k < len(clients); k++ { client := *clients[k] err := client.SendMessage(msg) if err != nil { stopClientListener(&client) client.Close() clients = deleteNthItem(clients, k) k-- //Account for socket deletion in slice fmt.Println("*** Disconnected irc Client. ", len(clients), "remaining.") } } //Received a message from the server case msg := <-fromClient: err := ircConn.Write(msg) if err != nil { fmt.Println("Error writing to server: ", err) } //A new client has connected case client := <-newClients: clients = append(clients, client) startClientListener(client, fromClient) fmt.Println("*** Accepted the ", len(clients), " client connection ***") } } quitChan <- true }
//ircServerListener continuallyu listens for messages from the IRC server. //When one is receives, it sends the message into the msg channel. func ircServerListener(ircConn irc.IRCConn, msgChan chan<- irc.Message, errChan chan<- error, quitChan <-chan bool) { fmt.Println("*** Entering ircListenerClient ***") defer fmt.Println("*** Leaving ircListenerClient ***") for { select { case <-quitChan: return default: msg, err := ircConn.Read() if err != nil { errChan <- err return } msgChan <- msg } } }