2012-06-11 8 views
6

Podczas pisania serwera sieci Web w urządzeniu GO (w moim przypadku przy użyciu kodeka JSON) można bezpiecznie używać dwóch różnych procedur Go do obsługi wysyłania i odbierania danych w tym samym połączeniu?Czy websocket wysyła/odbiera gwinty bezpieczne (przejdź do bezpiecznego rutowania)?

Od websocket.JSON.Receive zatrzymuje się i czeka na otrzymanie danych, myślałem, że oddzielna procedura Go do obsługi wysyłania danych będzie działającym rozwiązaniem, chyba że jednoczesne wysyłanie/odbieranie nie jest możliwe w tym samym połączeniu.

A więc, czy przykład działania znajduje się poniżej złej praktyki?

package main 

import (
    "fmt" 
    "net/http" 
    "code.google.com/p/go.net/websocket" 
) 

const queueSize = 20 

type Input struct { 
    Cmd string 
} 

type Output struct { 
    Cmd string 
} 

func Handler(ws *websocket.Conn) { 

    msgWrite := make(chan *Output, queueSize) 
    var in Input 

    go writeHandler(ws, msgWrite) 

    for { 

     err := websocket.JSON.Receive(ws, &in) 

     if err != nil { 
      fmt.Println(err) 
      break 
     } else { 
      msgWrite <- &Output{Cmd: "Thanks for your message: " + in.Cmd} 
     } 
    } 
} 

func writeHandler(ws *websocket.Conn, out chan *Output) { 
    var d *Output 
    for { 
     select { 
     case d = <-out: 
      if err := websocket.JSON.Send(ws, &d); err != nil { 
       fmt.Println(err.Error()) 
      } else { 
       fmt.Println("> ", d.Cmd) 
      } 
     } 
    } 
} 

func main() { 
    http.Handle("/echo", websocket.Handler(Handler)); 
    err := http.ListenAndServe(":1235", nil); 
    if err != nil { 
     panic("ListenAndServe: " + err.Error()) 
    } 
    fmt.Println("Server running") 
} 

Odpowiedz

9

Tak, możesz zadzwonić do wysyłania, odbierania i Close na połączenia websocket jednocześnie, jak to możliwe ze wszystkimi net.Conn JEST W Go. Krótki wyciąg z oficjalnych dokumentów:

Wiele goroutines może wywoływać metody na Conn jednocześnie.

Dodatkowo, pakiet websocket wprowadza także niektóre kodeki do wysyłania/zapisywania wiadomości lub danych JSON, które mogą zajmować wiele ramek atomowo. Jeśli spojrzysz na źródło, zobaczysz, że metoda Send and Receive typu Codec będzie zawierała blokadę odczytu lub zapisu.

+0

Dzięki za rozwiązanie! Brakowało mi szukania odpowiedzi w pakiecie sieciowym, więc cieszę się, że to wskazałeś. – ANisus

+0

@ tux21b gdzie widzisz, że spróbuje połączyć wiele ramek, aby utworzyć pojedynczą wiadomość JSON? Nie widzę tego w źródle i komentarzu zanim metoda tego nie zaznaczy: "// Odbierz otrzymuje __single frame from ws__, unmarshaled przez cd.Unmarshal, a store in v." Podkreśl moje. – Aktau

0

Cytat z http://www.gorillatoolkit.org/pkg/websocket

Współbieżnym

Połączenia obsługują jeden czytnik i jeden współbieżne współbieżne pisarza.

Aplikacje są odpowiedzialne za zapewnienie, że nie więcej niż jeden goroutine wywołuje metody write (NextWriter, SetWriteDeadline, WriteMessage, WriteJSON, EnableWriteCompression, SetCompressionLevel) jednocześnie i że nie więcej niż jeden goroutine wywołuje metody read (NextReader, SetReadDeadline, ReadMessage , ReadJSON, SetPongHandler, SetPingHandler) jednocześnie.

Metody Close i WriteControl można wywoływać jednocześnie z wszystkimi innymi metodami.

Powiązane problemy