2016-01-04 19 views
9

Jestem naiwnie używać _, err := ws.Read(msg), aby otworzyć gniazdo sieci Web w moim kodzie. Nie sądzę, że działa niezawodnie.Jak otworzyć stronę golang.org/x/net/websocket?

W innym kodzie zauważyłem, że ludzie robią sleep loop. Jaki jest poprawny sposób na utrzymanie gniazda sieciowego na otwartą & stabilną? Zakładam, że bazowa biblioteka wykonuje ping/ponga?

Aktualizacja: Jestem przekonany, że winę ponosi client.go, ponieważ nie wydaje się, aby ponownie wybrać numer po rozłączeniu na serwerze. Zrobiłem a video demonstrating the issue.

+0

Jestem również zainteresowany oglądaniem ping-ponga. Na przykład, jeśli klient idzie spać, chcę być w stanie powiedzieć, jaki jest czas, ostatni raz i tak dalej. – hendry

+0

Zaczynam myśleć, że to mój klient, to jest problem: https://github.com/kaihendry/WebSocketHook/tree/master/client Wydaje się, że nie jest on w stanie powiedzieć, kiedy jest odłączony. – hendry

+0

Tak, to prawda. Pomysł polega na tym, że gniazdo powinno pozostać otwarte i niezawodne, dopóki nie otrzyma ładunku wiadomości URL. Jednak w moim przykładzie nie jest on solidny. – hendry

Odpowiedz

6

Źle odczytałem pierwotne pytanie.

Nie robisz tego od razu. Zasadniczo trzeba zablokować obsługę programu, aby utrzymać połączenie sieci Web przy życiu. Jeśli nie zależy ci na wiadomości, po prostu ją odrzuć i nic z nią nie rób.

Częstym sposobem ludzie robią to mieć dedykowany Read i Write goroutine, coś jak:

func fishHandler(ws *websocket.Conn) { 
    id := ws.RemoteAddr().String() + "-" + ws.Request().RemoteAddr + "-" + ws.Request().UserAgent() 
    sockets[id] = ws 

    go writePump(ws) 
    readPump(ws) 
} 

func readPump(ws *websocket.Conn) { 
    defer ws.Close() 
    msg := make([]byte, 512) 
    _, err := ws.Read(msg) 
    if err != nil { 
     return 
    } 
} 

func writePump(ws *websocket.Conn) { 
    // Hand the write messages here 
} 
+0

Nie widzę powodu, dla którego potrzebna jest dedykowana gromada "Write", biorąc pod uwagę, że 'websocket.Conn.Write' jest wewnętrznie chroniony przez mutex. –

+0

Ma również sens wywołać 'ws.Close' po' ws.Read', w przypadku przypadkowego wysłania przez klienta wiadomości binarnej lub tekstowej. –

+0

Sprawdzanie 'err' w' ws.Read' nie ma w tym przypadku zbyt wielkiego sensu. –

6

golang.org/x/net/websocket nie implementuje do ping-ponga z RFC 6455, ale goryl websocket implementation robi. Minimalny przykład z webletem Gorilla

c := time.Tick(pingInterval) 
go func(){ 
     for _ := range c { 
      if err := conn.WriteControl(Ping...); err != nil { 
       handle error 
      } 
     } 
    }() 

      ----- 

conn.SetPongHandler(func(string) error { return conn.SetReadDeadline(time.Now().Add(pingInterval)) }) 
go func(){ 
     for { 
      if _, _, err := conn.NextReader(); err != nil { 
       handle error 
      } 
     } 
    }() 
+0

Nawet z "github.com/gorilla/websocket" nie ma minimalnego przykładu ping/ponga. Powiedziano mi, że https://github.com/gorilla/websocket/blob/master/examples/chat/conn.go jest punktem wyjścia, ale nie wyjaśnia, jak napisać plik binarny klienta i jak oglądać limity czasu i taki. – hendry

+0

@hendry I dodać minimalny przykład. – Uvelichitel

+0

Dzięki, choć nie do końca rozumiem, co zostało zaimplementowane przez klienta i co zostało zaimplementowane przez serwer. Czy mógłbyś uczynić to jaśniejszym? – hendry