github.com/graybobo/golang.org-package-offline-cache@v0.0.0-20200626051047-6608995c132f/x/talks/2012/chat/http/chat.go (about) 1 // +build OMIT 2 3 package main 4 5 import ( 6 "fmt" 7 "io" 8 "log" 9 "net/http" 10 11 "golang.org/x/net/websocket" 12 ) 13 14 const listenAddr = "localhost:4000" 15 16 func main() { 17 http.HandleFunc("/", rootHandler) 18 http.Handle("/socket", websocket.Handler(socketHandler)) 19 err := http.ListenAndServe(listenAddr, nil) 20 if err != nil { 21 log.Fatal(err) 22 } 23 } 24 25 type socket struct { 26 io.ReadWriter // HL 27 done chan bool 28 } 29 30 func (s socket) Close() error { 31 s.done <- true 32 return nil 33 } 34 35 func socketHandler(ws *websocket.Conn) { 36 s := socket{ws, make(chan bool)} // HL 37 go match(s) 38 <-s.done 39 } 40 41 // END OMIT 42 43 var partner = make(chan io.ReadWriteCloser) 44 45 func match(c io.ReadWriteCloser) { 46 fmt.Fprint(c, "Waiting for a partner...") 47 select { 48 case partner <- c: 49 // now handled by the other goroutine 50 case p := <-partner: 51 chat(p, c) 52 } 53 } 54 55 func chat(a, b io.ReadWriteCloser) { 56 fmt.Fprintln(a, "Found one! Say hi.") 57 fmt.Fprintln(b, "Found one! Say hi.") 58 errc := make(chan error, 1) 59 go cp(a, b, errc) 60 go cp(b, a, errc) 61 if err := <-errc; err != nil { 62 log.Println(err) 63 } 64 a.Close() 65 b.Close() 66 } 67 68 func cp(w io.Writer, r io.Reader, errc chan<- error) { 69 _, err := io.Copy(w, r) 70 errc <- err 71 }