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).