为什么grpc-go可以在相同的地址和端口上运行grpc服务器和http服务器,但是grpc-node无法运行

问题描述

我已经阅读了以下答案:https://stackoverflow.com/a/56943771/6463558,它说无法使用grpc-node包在相同的地址和端口上运行gRPC服务器和HTTP服务器。

但是我可以使用localhost:3000包在相同的地址和端口上创建gRPC服务器和HTTP服务器(例如,都使用grpc-go)。这是一个示例:https://github.com/mrdulin/grpc-go-cnode/blob/master/cmd/server/main.go#L79

因此,为什么grpc-node和grpc-go的行为不一致。这有道理吗?

我期望的结果是,无论在grpc中实现哪种语言,其行为都应保持一致。因此,grpc服务器应该能够与Node的标准库http在同一系统进程中创建的服务器共享同一端口。

解决方法

这与实现有关。每种语言都有自己的gRPC实现。每种语言的实现都有很多差异,一些是由于语言能力,还有维护者。每个项目都是一个不同的项目。

在这种情况下,我们不能真正说gRPC和HTTP服务器共享相同的地址。只有HTTP服务器正在运行。但是,用于gRPC服务器的Golang实现可以选择通过HTTP服务gRPC。

呼叫

server.ServeHTTP()

代替

server.Serve()

之所以可能,是因为gRPC服务器实际上是建立在顶级HTTP2之上的。

您分享的链接中的这段代码清楚了我的意思

if request.ProtoMajor != 2 {
            mux.ServeHTTP(writer,request)
            return
}

if strings.Contains(request.Header.Get("Content-Type"),"application/grpc") {
                grpcServer.ServeHTTP(writer,request)
                return
}

如果要在Node中执行相同的操作,则需要检查grpc-node的实现是否可用

,

您的示例使用Go standard library提供的http.NewServeMux()。 Node标准库没有提供等效功能,因此您不能以这种方式共享端口。