2015-09-23 4 views
5

In Go, wie kann ich den Browser starten, nachdem der Server zu hören begonnen hat?
Vorzugsweise der einfachste Weg möglich.Go: Wie kann ich den Browser NACH dem Starten des Servers starten?

Mein Code so weit, super verdummt auf den Punkt:

package main 

import ( 
    // Standard library packages 
    "fmt" 
    "net/http" 
    "github.com/skratchdot/open-golang/open" 
    // Third party packages 
    "github.com/julienschmidt/httprouter" 
) 


// go get github.com/toqueteos/webbrowser 

func main() { 
    // Instantiate a new router 
    r := httprouter.New() 

    // Add a handler on /test 
    r.GET("/test", func(w http.ResponseWriter, r *http.Request, _ httprouter.Params) { 
     // Simply write some test data for now 
     fmt.Fprint(w, "Welcome!\n") 
    }) 

    //open.Run("https://google.com/") 

    // open.Start("https://google.com") 

    // http://127.0.0.1:3000/test 
    // Fire up the server 
    http.ListenAndServe("localhost:3000", r) 
    fmt.Println("ListenAndServe is blocking") 
    open.RunWith("http://localhost:3000/test", "firefox") 
    fmt.Println("Done") 
} 
+4

In Go ist es nicht sehr kompliziert, das "blocking" 'http.ListenAndServe'" nonblocking "zu machen:' go http.ListenAndServe (...) ', vielleicht mit etwas Fehlerbehandlung. Also, was genau ist das Problem? – Volker

+0

@Volker: Das Problem ist, das sind meine ersten Schritte, also bin ich nicht sehr flüssig darin, aber ansonsten würde ich einfach einen neuen Thread erstellen und für ein paar Millisekunden schlafen, bevor ich den Browser öffne; und im Moment habe ich noch andere Dinge zu tun;) Wenn ListenAndServer nicht blockierend ist, würde es auch den Moment verlassen, wenn das Hauptprogramm beendet wird (AFAIK), was sofort der Fall wäre. –

Antwort

8

Wenn kein Fehler vorhanden ist, wird http.ListenAndServe() nie wieder zurückkehren. Sie sollten also keinen Code hinzufügen, außer Code, der Fehler verarbeitet.

Sie müssen eine neue Goroutine starten, also wird ListenAndServe() in einer Goroutine aufgerufen, und Codeüberprüfung, ob es oben ist, sollte auf der anderen Goroutine laufen.

Und Sie können überprüfen, ob Ihr Server aktiv ist, indem Sie einen einfachen HTTP-Aufruf GET, zum Beispiel mit http.Get() aufrufen.

Das folgende Beispiel verzögert den Start absichtlich für 7 Sekunden. Die neue goroutine startet eine endlose for-Schleife, die prüft, ob der Server aktiv ist und 1 Sekunde zwischen den Versuchen schläft.

Beispiel:

http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { 
    w.Write([]byte("Hi!")) 
}) 

go func() { 
    for { 
     time.Sleep(time.Second) 

     log.Println("Checking if started...") 
     resp, err := http.Get("http://localhost:8081") 
     if err != nil { 
      log.Println("Failed:", err) 
      continue 
     } 
     resp.Body.Close() 
     if resp.StatusCode != http.StatusOK { 
      log.Println("Not OK:", resp.StatusCode) 
      continue 
     } 

     // Reached this point: server is up and running! 
     break 
    } 
    log.Println("SERVER UP AND RUNNING!") 
}() 

log.Println("Starting server...") 
time.Sleep(time.Second * 7) 
log.Fatal(http.ListenAndServe(":8081", nil)) 

Beispiel Ausgabe:

2015/09/23 13:53:03 Starting server... 
2015/09/23 13:53:04 Checking if started... 
2015/09/23 13:53:06 Failed: Get http://localhost:8081: dial tcp [::1]:8081: connectex: No connection could be made because the target machine actively refused it. 
2015/09/23 13:53:07 Checking if started... 
2015/09/23 13:53:09 Failed: Get http://localhost:8081: dial tcp [::1]:8081: connectex: No connection could be made because the target machine actively refused it. 
2015/09/23 13:53:10 Checking if started... 
2015/09/23 13:53:10 SERVER UP AND RUNNING! 
14

Öffnen Sie den Hörer, den Browser starten und dann den Server-Schleife eingeben:

l, err := net.Listen("tcp", "localhost:3000") 
if err != nil { 
    log.Fatal(err) 
} 

// The browser can connect now because the listening socket is open. 

err := open.Start("http://localhost:3000/test") 
if err != nil { 
    log.Println(err) 
} 

// Start the blocking server loop. 

log.Fatal(http.Serve(l, r)) 

Es gibt keine Notwendigkeit abzufragen als in einer anderen Antwort gezeigt. Der Browser stellt eine Verbindung her, wenn der hörende Socket vor dem Start des Browsers geöffnet ist.

ListenAndServe ist eine Komfortfunktion, die einen Socket öffnet und Anrufe annimmt. Der Code in dieser Antwort teilt diese Schritte auf, sodass der Browser nach dem Start der Überwachung aber vor dem blockierenden Aufruf von Serve geöffnet werden kann.

+0

Interessant, ich mag es! Threading ist nicht einmal erforderlich. Sehr schön. –

+1

Das ist die richtige Antwort wirklich. Listening-Sockets haben eine interne Warteschlange für Backlogs mit fester Größe, die Verbindungen annehmen kann, selbst wenn zu einem gegebenen Zeitpunkt kein "Accept" aktiv wartet. Deshalb funktioniert es. – tomasz

+0

['server.ListenAndServe'] (https://golang.org/src/net/http/server.go#L2576) scheint auch einen' tcpKeepAliveListener' zu verwenden. Es scheint die TCP Keepalive von Sockets auf 3 Minuten zu setzen. Sie sollten das wahrscheinlich auch tun. – 0xcaff