The boolean variable ok returned by a receive operator indicates whether the received value was sent on the channel (true) or is a zero value returned because the channel is closed and empty (false).
The for loop terminates when some other part of the Go program closes the fromServer or the fromUser channel. In that case one of the case statements will set ok to true. So if the user closes the connection or the remote server closes the connection, the program will terminate.
http://play.golang.org/p/4fJDkgaa9O:
package main
import "runtime"
func onServer(i int) { println("S:", i) }
func onUser(i int) { println("U:", i) }
func main() {
fromServer, fromUser := make(chan int),make(chan int)
var serverData, userInput int
var ok bool
go func() {
fromServer <- 1
fromUser <- 1
close(fromServer)
runtime.Gosched()
fromUser <- 2
close(fromUser)
}()
isRunning := true
for isRunning {
select {
case serverData, ok = <-fromServer:
if ok {
onServer(serverData)
} else {
isRunning = false
}
case userInput, ok = <-fromUser:
if ok {
onUser(userInput)
} else {
isRunning = false
}
}
}
println("end")
}