@
目录写在前面
1. 需求
当 rpc 的服务启用时,为了更好对外提供服务(测试、监控、心跳等);我们需要多协议支持
-
- 起另外一个端口服务
-
- 同一个端口监听
-
- 同一个端口相同方法监听
1. 起另外的服务端口
package main
import (
"context"
"golang.org/x/net/http2"
"golang.org/x/net/http2/h2c"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials/insecure"
"google.golang.org/grpc/reflection"
"log"
"net/http"
"strings"
)
func main() {
port := "8080"
go handleHttp("8088")
handleRpc("8080")
}
func handleHttp(port string) *http.ServeMux {
m := http.NewServeMux()
m.HandleFunc("/ping", func(w http.ResponseWriter, r *http.Request) { w.Write([]byte("pong")) })
m.Handle("/", mux)
m.Serve()
//s := http.Server{Handler: m, Addr: "localhost:" + port}
return m
}
func handleRpc() {
//a := api.Api{Ctx: context.TODO(), Url: "http://localhost", Ak: "string", Sk: "string"}
//list, err := a.TagList()
//fmt.Printf("%#v,%s", list, err)
tag := server.NewTag("http://localhost", "string", "string")
svc := grpc.NewServer()
proto.RegisterTagSvcServer(svc, tag)
reflection.Register(svc)
svc.Serve()
}
2. 一个端口监听
package main
import (
"context"
"github.com/soheilhy/cmux"
"golang.org/x/net/http2"
"golang.org/x/net/http2/h2c"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials/insecure"
"google.golang.org/grpc/reflection"
"log"
"net/http"
"strings"
)
func main() {
port := "8080"
//go handleHttp("8088")
//handleRpc("8080")
//l, err := net.Listen("tcp", "localhost:"+port)
//if err != nil {
// log.Fatalf("Run TCP Server err: %v", err)
//}
m := cmux.New(l)
grpcL := m.MatchWithWriters(cmux.HTTP2MatchHeaderFieldPrefixSendSettings("content-type", "application/grpc"))
httpL := m.Match(cmux.HTTP1Fast())
grpcS := handleRpc()
httpS := handleHttp(port)
go grpcS.Serve(grpcL)
go httpS.Serve(httpL)
//
err = m.Serve()
if err != nil {
log.Fatalf("Run Serve err: %v", err)
}
}
func handleHttp(port string) *http.ServeMux {
m := http.NewServeMux()
m.HandleFunc("/ping", func(w http.ResponseWriter, r *http.Request) { w.Write([]byte("pong")) })
//s := http.Server{Handler: m, Addr: "localhost:" + port}
return m
}
func handleRpc() *grpc.Server {
//a := api.Api{Ctx: context.TODO(), Url: "http://localhost", Ak: "string", Sk: "string"}
//list, err := a.TagList()
//fmt.Printf("%#v,%s", list, err)
tag := server.NewTag("http://localhost", "string", "string")
//res, err := tag.TagList()
//if err != nil {
// return
//}
//fmt.Printf("%s,%s", res.String(), err)
svc := grpc.NewServer()
proto.RegisterTagSvcServer(svc, tag)
reflection.Register(svc)
return svc
}
func handleGrpcGateway(port string) *runtime.ServeMux {
endpoint := "0.0.0.0:" + port
g := runtime.NewServeMux()
dopts := []grpc.DialOption{grpc.WithTransportCredentials(insecure.NewCredentials())}
_ = proto.RegisterTagSvcHandlerFromEndpoint(context.Background(), g, endpoint, dopts)
return g
}
3. 同一个端口相同方法监听
# 1. 下载 Google API Proto 文件
git clone https://github.com/googleapis/googleapis.git
go install google.golang.org/protobuf/cmd/protoc-gen-go@latest
go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest
go install github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-grpc-gateway@latest
protoc -I . -I $GOPATH\github.com\googleapis --grpc-gateway_out=logtostderr=true:. --go_out=. --go-grpc_out . rpc/proto/*.proto
service TagSvc {
// protoc -I . -I $GOPATH\github.com\googleapis --grpc-gateway_out=logtostderr=true:. --go_out=. --go-grpc_out . rpc/proto/*.proto
rpc TagList(TagRequest) returns (MessageResponse){
option (google.api.http) = {
get: "/api/v1/tag"
};
}
}
package main
import (
"context"
"github.com/grpc-ecosystem/grpc-gateway/v2/runtime"
"golang.org/x/net/http2"
"golang.org/x/net/http2/h2c"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials/insecure"
"google.golang.org/grpc/reflection"
"log"
"net/http"
"strings"
)
func main() {
port := "8080"
grpcS := handleRpc()
grpcG := handleGrpcGateway(port)
httpS := handleHttp(port, grpcG)
err := http.ListenAndServe(":"+port, grpcHandlerFunc(grpcS, httpS))
if err != nil {
log.Fatalf("Run Serve err: %v", err)
}
}
func grpcHandlerFunc(grpcServer *grpc.Server, otherHandler http.Handler) http.Handler {
return h2c.NewHandler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.ProtoMajor == 2 && strings.Contains(r.Header.Get("Content-Type"), "application/grpc") {
grpcServer.ServeHTTP(w, r)
} else {
otherHandler.ServeHTTP(w, r)
}
}), &http2.Server{})
}
func handleHttp(port string, mux *runtime.ServeMux) *http.ServeMux {
m := http.NewServeMux()
m.HandleFunc("/ping", func(w http.ResponseWriter, r *http.Request) { w.Write([]byte("pong")) })
m.Handle("/", mux)
//s := http.Server{Handler: m, Addr: "localhost:" + port}
return m
}
func handleRpc() *grpc.Server {
//a := api.Api{Ctx: context.TODO(), Url: "http://localhost", Ak: "string", Sk: "string"}
//list, err := a.TagList()
//fmt.Printf("%#v,%s", list, err)
tag := server.NewTag("http://localhost", "string", "string")
//res, err := tag.TagList()
//if err != nil {
// return
//}
//fmt.Printf("%s,%s", res.String(), err)
svc := grpc.NewServer()
proto.RegisterTagSvcServer(svc, tag)
reflection.Register(svc)
return svc
}
func handleGrpcGateway(port string) *runtime.ServeMux {
endpoint := "0.0.0.0:" + port
g := runtime.NewServeMux()
dopts := []grpc.DialOption{grpc.WithTransportCredentials(insecure.NewCredentials())}
_ = proto.RegisterTagSvcHandlerFromEndpoint(context.Background(), g, endpoint, dopts)
return g
}
参考资料
基础/标准库/第三方库
golang 导航
编程规范
算法|面试
项目
标签:http,err,grpc,端口,golang,rpc,go,port From: https://www.cnblogs.com/nones/p/18236107