I have this problem where the function http.ListenAndServe()
blocks the goroutine, the simplified version of the original code was this:
package main
import (
"fmt"
"log"
"net/http"
)
func main() {
http.HandleFunc("/foo", func(w http.ResponseWriter, r *http.Request) {
fmt.Fprint(w, "visiting foo")
})
if err := http.ListenAndServe("127.0.0.1:8080", nil); err != nil {
log.Fatal(err)
}
fmt.Println("app succesfully running in url http://127.0.0.1:8080")
}
The problem is that the success message doesn't get printed out because http.ListenAndServe()
function blocks the goroutine, my first solution was this:
package main
import (
"fmt"
"log"
"net/http"
)
func main() {
http.HandleFunc("/foo", func(w http.ResponseWriter, r *http.Request) {
fmt.Fprint(w, "visiting foo")
})
go func() {
if err := http.ListenAndServe("127.0.0.1:8080", nil); err != nil {
log.Fatal(err)
}
}()
fmt.Println("app succesfully running in url http://127.0.0.1:8080")
var c chan struct{}
<-c
}
This is a very reasonable solution but it got a problem and it's that if http.ListenAndServe()
returns an error, the success message is also printed out, so another solution that I got was this but I don't like it, I hope you guys can help me with this:
package main
import (
"fmt"
"log"
"net/http"
"time"
)
func main() {
http.HandleFunc("/foo", func(w http.ResponseWriter, r *http.Request) {
fmt.Fprint(w, "visiting foo")
})
go func() {
if err := http.ListenAndServe("127.0.0.1:8080", nil); err != nil {
log.Fatal(err)
}
}()
someArbitraryDuration := 100 * time.Millisecond
time.Sleep(someArbitraryDuration)
fmt.Println("app succesfully running in url http://127.0.0.1:8080")
var c chan struct{}
<-c
}
I thought that in the net/http
package there was some function that received a channel or callback function just like the Express JS framework has.
If you can help me with this, some way to pass a channel or callback to a function similar to ListenAndServe()
.
Unfortunately I couldn't get the code to work on Go Playground (Official Website).
If you want to print a success message after the server start accepting connection you can use net.Listen
. For example:
l, err := net.Listen("tcp", ":8080")
if err == nil {
fmt.Println("Listening on port 8080")
}
http.Serve(l, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Hello World")
}))