2015-07-30 01:57:51 +08:00
|
|
|
# cmux: Connection Mux ![Travis Build Status](https://api.travis-ci.org/soheilhy/args.svg?branch=master "Travis Build Status") [![GoDoc](https://godoc.org/github.com/soheilhy/cmux?status.svg)](http://godoc.org/github.com/soheilhy/cmux)
|
|
|
|
|
2015-07-30 01:45:57 +08:00
|
|
|
cmux is a generic Go library to multiplex connections based on
|
2015-08-01 23:58:14 +08:00
|
|
|
their payload. Using cmux, you can serve gRPC, SSH, HTTPS, HTTP,
|
2015-08-02 00:44:34 +08:00
|
|
|
Go RPC, and pretty much any other protocol on the same TCP listener.
|
2015-07-30 01:45:57 +08:00
|
|
|
|
|
|
|
## How-To
|
|
|
|
Simply create your main listener, create a cmux for that listener,
|
|
|
|
and then match connections:
|
|
|
|
```go
|
|
|
|
// Create the main listener.
|
|
|
|
l, err := net.Listen("tcp", ":23456")
|
|
|
|
if err != nil {
|
|
|
|
log.Fatal(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Create a cmux.
|
|
|
|
m := cmux.New(l)
|
|
|
|
|
2015-07-30 23:03:07 +08:00
|
|
|
// Match connections in order:
|
|
|
|
// First grpc, then HTTP, and otherwise Go RPC/TCP.
|
2022-01-11 05:26:07 +08:00
|
|
|
// cmux.HTTP2MatchHeaderFieldSendSettings ensures we can handle any gRPC client.
|
|
|
|
grpcL := m.MatchWithWriters(cmux.HTTP2MatchHeaderFieldSendSettings("content-type", "application/grpc"))
|
2015-07-30 23:03:07 +08:00
|
|
|
httpL := m.Match(cmux.HTTP1Fast())
|
|
|
|
trpcL := m.Match(cmux.Any()) // Any means anything that is not yet matched.
|
2015-07-30 01:45:57 +08:00
|
|
|
|
|
|
|
// Create your protocol servers.
|
|
|
|
grpcS := grpc.NewServer()
|
2018-05-17 02:19:32 +08:00
|
|
|
grpchello.RegisterGreeterServer(grpcS, &server{})
|
2015-07-30 01:45:57 +08:00
|
|
|
|
|
|
|
httpS := &http.Server{
|
2015-07-30 05:35:55 +08:00
|
|
|
Handler: &helloHTTP1Handler{},
|
2015-07-30 01:45:57 +08:00
|
|
|
}
|
|
|
|
|
2015-07-30 23:03:07 +08:00
|
|
|
trpcS := rpc.NewServer()
|
2017-05-22 20:38:03 +08:00
|
|
|
trpcS.Register(&ExampleRPCRcvr{})
|
2015-07-30 23:03:07 +08:00
|
|
|
|
2015-07-30 01:45:57 +08:00
|
|
|
// Use the muxed listeners for your servers.
|
2015-07-30 02:02:24 +08:00
|
|
|
go grpcS.Serve(grpcL)
|
|
|
|
go httpS.Serve(httpL)
|
2015-07-30 23:03:07 +08:00
|
|
|
go trpcS.Accept(trpcL)
|
2015-07-30 01:45:57 +08:00
|
|
|
|
|
|
|
// Start serving!
|
|
|
|
m.Serve()
|
|
|
|
```
|
|
|
|
|
2015-07-30 02:40:09 +08:00
|
|
|
Take a look at [other examples in the GoDoc](http://godoc.org/github.com/soheilhy/cmux/#pkg-examples).
|
2015-07-30 01:45:57 +08:00
|
|
|
|
|
|
|
## Docs
|
|
|
|
* [GoDocs](https://godoc.org/github.com/soheilhy/cmux)
|
|
|
|
|
|
|
|
## Performance
|
2015-07-30 02:53:29 +08:00
|
|
|
There is room for improvment but, since we are only matching
|
2015-07-30 01:45:57 +08:00
|
|
|
the very first bytes of a connection, the performance overheads on
|
|
|
|
long-lived connections (i.e., RPCs and pipelined HTTP streams)
|
|
|
|
is negligible.
|
|
|
|
|
|
|
|
*TODO(soheil)*: Add benchmarks.
|
|
|
|
|
|
|
|
## Limitations
|
2015-12-12 04:22:57 +08:00
|
|
|
* *TLS*: `net/http` uses a type assertion to identify TLS connections; since
|
|
|
|
cmux's lookahead-implementing connection wraps the underlying TLS connection,
|
|
|
|
this type assertion fails.
|
2015-07-30 22:00:00 +08:00
|
|
|
Because of that, you can serve HTTPS using cmux but `http.Request.TLS`
|
|
|
|
would not be set in your handlers.
|
2015-07-30 12:07:14 +08:00
|
|
|
|
|
|
|
* *Different Protocols on The Same Connection*: `cmux` matches the connection
|
|
|
|
when it's accepted. For example, one connection can be either gRPC or REST, but
|
|
|
|
not both. That is, we assume that a client connection is either used for gRPC
|
|
|
|
or REST.
|
2016-04-25 02:52:49 +08:00
|
|
|
|
2016-07-10 02:01:36 +08:00
|
|
|
# Copyright and License
|
|
|
|
Copyright 2016 The CMux Authors. All rights reserved.
|
|
|
|
|
|
|
|
See [CONTRIBUTORS](https://github.com/soheilhy/cmux/blob/master/CONTRIBUTORS)
|
|
|
|
for the CMux Authors. Code is released under
|
|
|
|
[the Apache 2 license](https://github.com/soheilhy/cmux/blob/master/LICENSE).
|