// This example demonstrates a trivial echo server. func ExampleHandler() { http.Handle("/echo", websocket.Handler(EchoServer)) err := http.ListenAndServe(":12345", nil) if err != nil { panic("ListenAndServe: " + err.Error()) } }
// 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 main() { var addr, consul, name, prefix, proto string flag.StringVar(&addr, "addr", "127.0.0.1:5000", "host:port of the service") flag.StringVar(&consul, "consul", "127.0.0.1:8500", "host:port of the consul agent") flag.StringVar(&name, "name", filepath.Base(os.Args[0]), "name of the service") flag.StringVar(&prefix, "prefix", "", "comma-sep list of host/path prefixes to register") flag.StringVar(&proto, "proto", "http", "protocol for endpoints: http or ws") flag.Parse() if prefix == "" { flag.Usage() os.Exit(1) } // register prefixes prefixes := strings.Split(prefix, ",") for _, p := range prefixes { switch proto { case "http": http.HandleFunc(p, func(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, "Serving %s from %s on %s\n", r.RequestURI, name, addr) }) case "ws": http.Handle(p, websocket.Handler(EchoServer)) default: log.Fatal("Invalid protocol ", proto) } } // start http server go func() { log.Printf("Listening on %s serving %s", addr, prefix) if err := http.ListenAndServe(addr, nil); err != nil { log.Fatal(err) } }() // register consul health check endpoint http.HandleFunc("/health", func(w http.ResponseWriter, r *http.Request) { fmt.Fprintln(w, "OK") }) // build urlprefix-host/path tag list // e.g. urlprefix-/foo, urlprefix-/bar, ... var tags []string for _, p := range prefixes { tags = append(tags, "urlprefix-"+p) } // get host and port as string/int host, portstr, err := net.SplitHostPort(addr) if err != nil { log.Fatal(err) } port, err := strconv.Atoi(portstr) if err != nil { log.Fatal(err) } // register service with health check serviceID := name + "-" + addr service := &api.AgentServiceRegistration{ ID: serviceID, Name: name, Port: port, Address: host, Tags: tags, Check: &api.AgentServiceCheck{ HTTP: "http://" + addr + "/health", Interval: "1s", Timeout: "1s", }, } config := &api.Config{Address: consul, Scheme: "http"} client, err := api.NewClient(config) if err != nil { log.Fatal(err) } if err := client.Agent().ServiceRegister(service); err != nil { log.Fatal(err) } log.Printf("Registered service %q in consul with tags %q", name, strings.Join(tags, ",")) // run until we get a signal quit := make(chan os.Signal, 1) signal.Notify(quit, os.Interrupt, os.Kill) <-quit // deregister service if err := client.Agent().ServiceDeregister(serviceID); err != nil { log.Fatal(err) } log.Printf("Deregistered service %q in consul", name) }
func (p *wsProxy) ServeHTTP(w http.ResponseWriter, r *http.Request) { websocket.Handler(wsHandler).ServeHTTP(w, r) }