2016-01-04 11 views
9

Uso ingenuo _, err := ws.Read(msg) per mantenere aperto un socket Web nel mio codice. Non penso che funzioni in modo affidabile.Come mantenere aperto un golang.org/x/net/websocket?

In altri codici ho notato persone che fanno uno sleep loop. Qual è il modo corretto per mantenere aperto un socket Web & stabile? Presumo che la libreria sottostante faccia ping/pongs?

Aggiornamento: Sono abbastanza fiducioso che il client.go è la colpa poiché non sembra riselezionare dopo una disconnessione è visto sul server. Ho fatto a video demonstrating the issue.

+0

Sono anche entusiasta di vedere ping/pongs. Ad esempio, se il cliente va a dormire, voglio essere in grado di dire che cos'è il time out, l'ultima vista e così via. – hendry

+0

Iniziare a pensare che sia il mio cliente il problema: https://github.com/kaihendry/WebSocketHook/tree/master/client Sembra non essere in grado di dire quando è disconnesso. – hendry

+0

Sì, è vero. L'idea è che il socket debba rimanere aperto e robusto finché non riceve il payload del messaggio URL. Tuttavia nel mio esempio non è robusto. – hendry

risposta

6

Ho letto male la tua domanda originale.

No, lo stai facendo subito. Fondamentalmente è necessario bloccare il gestore per tornare a mantenere in vita la connessione web. Se non ti interessa il messaggio, scartalo e non fare nulla con esso.

Un modo comune le persone lo fanno è quello di avere un apposito Read e Write goroutine, qualcosa di simile a:

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

Non vedo perché sia ​​necessaria una goroutine di 'Write' dedicata, considerando che' websocket.Conn.Write' è protetto internamente da un mutex. –

+0

Ha anche senso chiamare 'ws.Close' dopo' ws.Read', nel caso in cui un messaggio binario o di testo venga inviato accidentalmente dal client. –

+0

Anche il controllo di 'ws.Read' err 'non ha molto senso in questo caso. –

6

golang.org/x/net/websocket non implementa ping-pong da RFC 6455, ma la webs gorilla implementation fa. Esempio minimo con ragnatela di 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

Anche con "github.com/gorilla/websocket", non esiste un esempio ping/pong minimo. Mi è stato detto che https://github.com/gorilla/websocket/blob/master/examples/chat/conn.go è un punto di partenza, ma non spiega come scrivere un client binario e come guardare i timeout e come. – hendry

+0

@ hendry aggiungo un esempio minimo. – Uvelichitel

+0

Grazie, anche se non capisco cosa è implementato dal client e cosa è implementato dal server. Potresti renderlo più chiaro? – hendry

Problemi correlati