Hi, It seems you assume that the server sends a single response for each message received. But don't forget that WebSocket is fully duplex and the server can send multiple messages at any time while you wait for input.
Regards, Kwang Yul Seo On Sun, Sep 25, 2016 at 10:02 PM, mhhcbon <cpasmaboiteas...@gmail.com> wrote: > fixes a few edge cases i ran into, see the main for loop, > rather than requesting for input on each iteration, asks for it only when > needed, > > package main > > import ( > "flag" > "fmt" > // "bufio" > // "os" > "net/http" > "io" > "time" > > > "github.com/chzyer/readline" > ws "github.com/gorilla/websocket" > ) > > > func dial(url string, origin string, subprotocol string) (*ws.Conn, error) > { > var subprotocols []string > var header http.Header > > if subprotocol != "" { > subprotocols = []string{subprotocol} > } > if origin != "" { > header = http.Header{"Origin": {origin}} > } > > dialer := ws.Dialer{ > Subprotocols: subprotocols, > ReadBufferSize: 1024, > WriteBufferSize: 1024, > } > > conn, _, err := dialer.Dial(url, header) > return conn, err > } > > func writeConn (conn *ws.Conn) (chan<-[]byte, chan bool, chan error) { > write := make(chan []byte) > done := make(chan bool) > errc := make(chan error) > go func () { > for { > select { > case data := <-write: > err := conn.WriteMessage(ws.TextMessage, data) > if err !=nil { > errc <- err > } > case <-done: > close(write) > close(done) > close(errc) > return > } > } > }() > return write, done, errc > } > > func readLine () (<-chan []byte, chan<-bool, chan bool, chan error) { > read := make(chan []byte) > done := make(chan bool) > errc := make(chan error) > want := make(chan bool) > go func () { > rl, err := readline.New("> ") > if err!=nil{ > errc <- err > return > } > // reader := bufio.NewReader(os.Stdin) > for { > select { > case <-want: > // data, err := reader.ReadBytes('\n') > // if err != nil { > // errc <- err > // } > line, err := rl.Readline() > if err == io.EOF { > fmt.Println("EOF") > } else if err != nil { > errc <- err > // log.Fatalf("ReadLine: %v", err) > } else { > read<-[]byte(line) > } > > // read<-data[:len(data)-1] > case <-done: > close(want) > close(read) > close(done) > close(errc) > rl.Close() > return > } > } > }() > return read, want, done, errc > } > > func readConn (conn *ws.Conn) (<-chan []byte, chan<-bool, chan bool, chan > error) { > read := make(chan []byte) > done := make(chan bool) > want := make(chan bool) > errc := make(chan error) > go func () { > for { > select { > case <-want: > _, data, err := conn.ReadMessage() > if err != nil { > errc <- err > } > read<-data > case <-done: > close(read) > close(want) > close(done) > close(errc) > return > } > } > }() > return read, want, done, errc > } > > > func main () { > > var url = flag.String("url", "ws://echo.websocket.org", "url") > var origin = flag.String("origin", "", "optional origin") > var subprotocol = flag.String("subprotocol", "", "optional > subprotocol") > flag.Parse() > if *url == "" { > flag.Usage() > return > } > > conn, err := dial(*url, *origin, *subprotocol) > if err!=nil { > panic(err) > } > > write, writeEnd, writeErr := writeConn(conn) > read, wantRes, readEnd, readErr := readConn(conn) > rl, wantRl, rlEnd, rlErr := readLine() > > terminate := func () { > rlEnd<-true > readEnd<-true > writeEnd<-true > conn.Close() > } > > prompt := func () { > // fmt.Print("> ") > wantRl <- true > } > > prompt() > for { > select { > > case line := <-rl: > if len(line)==0 { > fmt.Printf("Type in a message!\n") > prompt() > > } else if string(line)=="quit" { > fmt.Println("Bye!") > terminate() > return > > } else { > write <- line > wantRes <- true > } > > case res := <-read: > fmt.Printf("response: %v\n", string(res)) > prompt() > > case err := <-rlErr: > if err == readline.ErrInterrupt { > fmt.Println("Interrupted") > } else { > fmt.Printf("error while reading stdin, %v\n", err) > } > terminate() > return > > case err := <-readErr: > fmt.Printf("error while reading WS, %v\n", err) > terminate() > return > > case err := <-writeErr: > fmt.Printf("error while writing WS, %v\n", err) > terminate() > return > } > } > > <-time.After(time.Second * 1) > } > > > > -- > You received this message because you are subscribed to the Google Groups > "golang-nuts" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to golang-nuts+unsubscr...@googlegroups.com. > For more options, visit https://groups.google.com/d/optout. > -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.