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  }