func main() { var url, origin string flag.StringVar(&url, "url", "ws://127.0.0.1:9999/echo", "websocket URL") flag.StringVar(&origin, "origin", "http://localhost/", "origin header") flag.Parse() if url == "" { flag.Usage() os.Exit(1) } ws, err := websocket.Dial(url, "", origin) if err != nil { log.Fatal(err) } go func() { var msg = make([]byte, 512) for { n, err := ws.Read(msg) if err != nil { log.Fatal(err) } fmt.Printf("R: %s\nS: ", msg[:n]) } }() fmt.Print("S: ") sc := bufio.NewScanner(os.Stdin) for sc.Scan() { if _, err := ws.Write(sc.Bytes()); err != nil { log.Fatal(err) } } }
// newWSProxy returns a websocket handler which forwards // messages from an incoming WS connection to an outgoing // WS connection. It builds upon the golang.org/x/net/websocket // library for both incoming and outgoing connections. func newWSProxy(t *url.URL) http.Handler { return websocket.Handler(func(in *websocket.Conn) { defer in.Close() r := in.Request() targetURL := "ws://" + t.Host + r.RequestURI out, err := websocket.Dial(targetURL, "", r.Header.Get("Origin")) if err != nil { log.Printf("[INFO] WS error for %s. %s", r.URL, err) return } defer out.Close() errc := make(chan error, 2) cp := func(dst io.Writer, src io.Reader) { _, err := io.Copy(dst, src) errc <- err } go cp(out, in) go cp(in, out) err = <-errc if err != nil && err != io.EOF { log.Printf("[INFO] WS error for %s. %s", r.URL, err) } }) }
func wsHandler(client *websocket.Conn) { r := client.Request() t := target(r) if t == nil { client.WriteClose(http.StatusNotFound) return } logerr := func(err error) { if err != nil && err != io.EOF { log.Printf("[INFO] WS error for %s. %s", r.URL, err) } } // dial the server origin := r.Header.Get("Origin") targetURL := "ws://" + t.URL.Host + r.RequestURI server, err := websocket.Dial(targetURL, "", origin) if err != nil { logerr(err) return } // send data from client to server cerr := make(chan error) go func() { _, err := io.Copy(server, client) cerr <- err }() // send data from server to client serr := make(chan error) go func() { _, err = io.Copy(client, server) serr <- err }() // wait for either server or client to exit // and then close the other side start := time.Now() select { case err := <-cerr: logerr(err) server.Close() case err := <-serr: logerr(err) client.Close() } t.Timer.UpdateSince(start) }
// This example demonstrates a trivial client. func ExampleDial() { origin := "http://localhost/" url := "ws://localhost:12345/ws" ws, err := websocket.Dial(url, "", origin) if err != nil { log.Fatal(err) } if _, err := ws.Write([]byte("hello, world!\n")); err != nil { log.Fatal(err) } var msg = make([]byte, 512) var n int if n, err = ws.Read(msg); err != nil { log.Fatal(err) } fmt.Printf("Received: %s.\n", msg[:n]) }