(摘) cmux 端口复用

声明:内容源自网络,版权归原作者所有。若有侵权请在网页聊天中联系我

cmux 是一个通用的 Go 库,用于根据有效载荷复用连接。使用 cmux,你可以在同一个 TCP 监听器上提供 gRPC、SSH、HTTPS、HTTP、Go RPC 以及几乎所有其他协议的服务。

// Create the main listener.
l, err := net.Listen("tcp", ":23456")
if err != nil {
	log.Fatal(err)
}

// Create a cmux.
m := cmux.New(l)

// Match connections in order:
// First grpc, then HTTP, and otherwise Go RPC/TCP.
grpcL := m.Match(cmux.HTTP2HeaderField("content-type", "application/grpc"))
httpL := m.Match(cmux.HTTP1Fast())
trpcL := m.Match(cmux.Any()) // 任何表示尚未匹配的任何内容

// 创建你的协议服务器
grpcS := grpc.NewServer()
grpchello.RegisterGreeterServer(grpcS, &server{})

httpS := &http.Server{
	Handler: &helloHTTP1Handler{},
}

trpcS := rpc.NewServer()
trpcS.Register(&ExampleRPCRcvr{})

// Use the muxed listeners for your servers.
go grpcS.Serve(grpcL)
go httpS.Serve(httpL)
go trpcS.Accept(trpcL)

// Start serving!
m.Serve()
package main

import (
	"context"
	"log"
	"net"
	"net/http"

	"google.golang.org/grpc"
	pb "google.golang.org/grpc/examples/helloworld/helloworld"

	"github.com/soheilhy/cmux"
)

func main() {
	lis, err := net.Listen("tcp", "localhost:50051")
	if err != nil {
		log.Fatalf("failed to listen: %v", err)
	}

	mux := cmux.New(lis)

	// gRPC 匹配规则
	grpcL := mux.MatchWithWriters(
		cmux.HTTP2MatchHeaderFieldSendSettings("content-type", "application/grpc"),
	)
	// otherwise serve http
	httpL := mux.Match(cmux.Any())

	// gRPC server
	grpcS := grpc.NewServer()
	pb.RegisterGreeterServer(grpcS, &server{})

	// HTTP server
	httpS := &http.Server{
		Handler: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
			w.Write([]byte("greet from HTTP\n"))
		}),
	}

	// start serving!
	go grpcS.Serve(grpcL)
	go httpS.Serve(httpL)
	log.Printf("serve both grpc and http at %v", lis.Addr())
	if err := mux.Serve(); err != nil {
		log.Fatalf("failed to serve: %v", err)
	}
}

type server struct {
	pb.UnimplementedGreeterServer
}

func (*server) SayHello(ctx context.Context, in *pb.HelloRequest) (*pb.HelloReply, error) {
	return &pb.HelloReply{Message: "greet from gRPC"}, nil
}

相关文章