Created
April 16, 2016 17:12
-
-
Save sgade/517b9763d99b4d01f3065f7342910a84 to your computer and use it in GitHub Desktop.
Golang Streaming Server
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"fmt" | |
"net/http" | |
"sync" | |
"time" | |
) | |
func main() { | |
// create a global counter and a mutex for it | |
mutex := sync.Mutex{} | |
i := 1 | |
http.HandleFunc("/", func(rw http.ResponseWriter, req *http.Request) { | |
mutex.Lock() | |
index := i | |
i++ | |
mutex.Unlock() | |
// the function sending text during execution | |
var waitingText func(string) | |
// the function sending text that is not time critical | |
var contentText func(string) | |
if hj, ok := rw.(http.Hijacker); ok { | |
// hijack the connection | |
if con, bufrw, err := hj.Hijack(); err != nil { | |
http.Error(rw, fmt.Sprintf("Could not hijack connection: %v.", err.Error()), http.StatusInternalServerError) | |
return | |
} else { | |
// we are now responsible for the connection and its data flow | |
// so make sure to close the connection in the end | |
defer con.Close() | |
// and also flush all pending data to the client | |
defer bufrw.Flush() | |
contentText = func(input string) { | |
// simply send the text | |
if length, err := bufrw.WriteString(input); err != nil { | |
panic(err) | |
} else { | |
fmt.Printf("Sent %q (%v bytes).\n", input, length) | |
} | |
} | |
waitingText = func(input string) { | |
// send the text | |
contentText(input) | |
// make sure it is immediately flushed to the client | |
if err := bufrw.Flush(); err != nil { | |
panic(err) | |
} | |
fmt.Printf("Sent waiting text.\n") | |
} | |
} | |
} else { | |
fmt.Printf("Streaming not supported.\n") | |
waitingText = func(input string) { | |
// nothing | |
rw.WriteHeader(http.StatusOK) | |
} | |
contentText = func(input string) { | |
rw.Write([]byte(input)) | |
} | |
} | |
// user-interaction | |
fmt.Printf("Request %v received.\n", index) | |
waitingText(fmt.Sprintf("Welcome Nr.%v. Plase wait...\n", index)) | |
select { | |
case <-time.After(3 * time.Second): | |
contentText("\n") | |
contentText("Hello World\n") | |
fmt.Printf("Request %v responded to.\n", index) | |
} | |
}) | |
// start the server | |
done := make(chan bool) | |
go func() { | |
err := http.ListenAndServe(":3000", nil) | |
fmt.Printf("Server crashed: %v.", err) | |
done <- true | |
}() | |
fmt.Printf("Server started!\n") | |
<-done | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment