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) }
func EchoServer(ws *websocket.Conn) { addr := ws.LocalAddr().String() pfx := []byte("[" + addr + "] ") log.Printf("ws connect on %s", addr) // the following could be done with io.Copy(ws, ws) // but I want to add some meta data var msg = make([]byte, 1024) for { n, err := ws.Read(msg) if err != nil && err != io.EOF { log.Printf("ws error on %s. %s", addr, err) break } _, err = ws.Write(append(pfx, msg[:n]...)) if err != nil && err != io.EOF { log.Printf("ws error on %s. %s", addr, err) break } } log.Printf("ws disconnect on %s", addr) }