github.com/searKing/golang/go@v1.2.117/net/mux/README.md (about)

     1  [![Build Status](https://travis-ci.org/searKing/travis-ci.svg?branch=mux)](https://travis-ci.org/searKing/travis-ci)
     2  [![GoDoc](https://godoc.org/github.com/searKing/golang/tools/mux?status.svg)](https://godoc.org/github.com/searKing/golang/go/net/mux)
     3  [![Report card](https://goreportcard.com/badge/github.com/searKing/golang/tools/mux)](https://goreportcard.com/report/github.com/searKing/golang/go/net/mux)
     4  [![Sourcegraph](https://sourcegraph.com/github.com/searKing/golang/-/badge.svg)](https://sourcegraph.com/github.com/searKing/travis-ci@mux?badge)
     5  
     6  # mux: Connection Mux
     7  
     8  mux is a generic Go library to multiplex connections based on their payload. Using mux, you can serve gRPC, SSH, HTTPS,
     9  HTTP, Go RPC, and pretty much any other protocol on the same TCP listener.
    10  
    11  ## How-To
    12  
    13  Simply create your main listener, create a mux for that listener, and then match connections:
    14  
    15  ```go
    16  package main
    17  
    18  import (
    19  	"context"
    20  	"log"
    21  	"net/http"
    22  	"os"
    23  	"os/signal"
    24  	"strings"
    25  
    26  	"github.com/searKing/golang/go/net/mux"
    27  	"golang.org/x/net/http2/hpack"
    28  )
    29  
    30  func main() {
    31  	srv := mux.NewServer()
    32  	defer srv.Close()
    33  
    34  	// We first match the connection against HTTP2 fields. If matched, the
    35  	// connection will be sent through the "grpcl" listener.
    36  	grpcl := mux.HandleListener(mux.HTTP2HeaderFieldValue(false, strings.EqualFold, hpack.HeaderField{
    37  		Name:  "Content-Type",
    38  		Value: "application/grpc",
    39  	}))
    40  	//Otherwise, we match it againts a websocket upgrade request.
    41  	var wslH = http.Header{}
    42  	wslH.Set("Upgrade", "websocket")
    43  	wsl := mux.HandleListener(mux.HTTP1HeaderEqual(wslH))
    44  
    45  	// Otherwise, we match it againts HTTP1 methods. If matched,
    46  	// it is sent through the "httpl" listener.
    47  	httpl := mux.HandleListener(mux.HTTP1Fast())
    48  	// If not matched by HTTP, we assume it is an RPC connection.
    49  	rpcl := mux.HandleListener(mux.Any())
    50  
    51  	// Then we used the muxed listeners.
    52  	// See safeServe in github.com/searKing/golang/go/net/mux/mux_helper_test.go
    53  	go serveGRPC(grpcl)
    54  	go serveWS(wsl)
    55  	go serveHTTP(httpl)
    56  	go serveRPC(rpcl)
    57  
    58  	idleConnsClosed := make(chan struct{})
    59  	go func() {
    60  		sigint := make(chan os.Signal, 1)
    61  		signal.Notify(sigint, os.Interrupt)
    62  		<-sigint
    63  
    64  		// We received an interrupt signal, shut down.
    65  		if err := srv.Shutdown(context.Background()); err != nil {
    66  			// Error from closing listeners, or context timeout:
    67  			log.Printf("mux server Shutdown: %v", err)
    68  		}
    69  		close(idleConnsClosed)
    70  	}()
    71  	if err := srv.ListenAndServe("localhost:0"); err != mux.ErrServerClosed {
    72  		// Error starting or closing listener:
    73  		log.Printf("mux server ListenAndServe: %v", err)
    74  	}
    75  	<-idleConnsClosed
    76  }
    77  ```
    78  
    79  Take a look at [other examples in the GoDoc](http://godoc.org/github.com/searKing/golang/go/net/mux/#pkg-examples).
    80  
    81  ## Docs
    82  
    83  * [GoDocs](https://godoc.org/github.com/searKing/golang/go/net/mux)
    84  
    85  ## Performance
    86  
    87  There is room for improvment but, since we are only matching the very first bytes of a connection, the performance
    88  overheads on long-lived connections (i.e., RPCs and pipelined HTTP streams)
    89  is negligible.
    90  
    91  ## Limitations
    92  
    93  * *TLS*: `net/http` uses a type assertion to identify TLS connections; since mux's lookahead-implementing connection
    94    wraps the underlying TLS connection, this type assertion fails. Because of that, you can serve HTTPS using mux
    95    but `http.Request.TLS`
    96    would not be set in your handlers.
    97  
    98  * *Different Protocols on The Same Connection*: `mux` matches the connection when it's accepted. For example, one
    99    connection can be either gRPC or REST, but not both. That is, we assume that a client connection is either used for
   100    gRPC or REST.
   101  
   102  * *Java gRPC Clients*: Java gRPC client blocks until it receives a SETTINGS frame from the server. If you are using the
   103    Java client to connect to a mux'ed gRPC server please match with writers:
   104  
   105  ```go
   106  package main
   107  
   108  import (
   109  	"strings"
   110  
   111  	"github.com/searKing/golang/go/net/mux"
   112  	"golang.org/x/net/http2/hpack"
   113  )
   114  
   115  func main() {
   116  	grpcl := mux.HandleListener(mux.HTTP2HeaderFieldValue(false, strings.EqualFold, hpack.HeaderField{
   117  		Name:  "Content-Type",
   118  		Value: "application/grpc",
   119  	}))
   120  	_ = grpcl
   121  }
   122  ```
   123  
   124  ## Thanks to
   125  
   126  + [cmux](https://github.com/soheilhy/cmux.git).
   127  
   128  # Copyright and License
   129  
   130  Copyright 2019 The searKing Authors. All rights reserved.
   131  
   132  Code is released under
   133  [the MIT license](https://github.com/searKing/golang/go/net/mux/blob/master/LICENSE).