英文:
gRPC and HTTP 1 call on single port, with out using TLS in goLang
问题
我最近开始在一个项目中使用golang,其中我需要在服务器上使用gRPC进行推送通知,以连接到Android设备。我已经创建了一个简单的多路复用器mux := http.NewServeMux()
,在我的服务器代码中运行良好:
serverWeb := http.Server{
Addr: constants.ServerIPWeb,
Handler: mux,
}
serverWeb.ListenAndServe()
根据gRPC.io上的示例,我还创建了一个简单的独立的gRPC客户端/服务器项目,连接到我的Android设备,没有任何TLS
配置,它也正常工作。
type server struct{}
func (s *server) DeviceData(ctx context.Context, req *pb.GetDeviceRequest) (*pb.SetDeviceResponse, error) {
util.P("Device is: ", req) // 简单的 fmt.PrintF(a ... interface)
return &pb.SetDeviceResponse{Message: "Success"}, nil
}
func main() {
lis, err := net.Listen("tcp", ":8080")
if err != nil {
log.Fatalf("Failed to listen: %v", err)
}
s := grpc.NewServer()
pb.RegisterDeviceInfoServer(s, &server{})
reflection.Register(s)
if err := s.Serve(lis); err != nil {
log.Fatalf("Falied to server: %v", err)
}
}
问题是我无法将我的当前gRPC服务器连接到上面的serverStruct
。我尝试添加Handler: grpcHandlerFunc(grpcServer, mux)
,将我的服务器连接到以下代码,如这里所解释的(gRPC与开放API):
func grpcHandlerFunc(grpcServer *grpc.Server, otherHandler http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// TODO(tamird): point to merged gRPC code rather than a PR.
// This is a partial recreation of gRPC's internal checks https://github.com/grpc/grpc-go/pull/514/files#diff-95e9a25b738459a2d3030e1e6fa2a718R61
util.P("ResponseFunction: GRPC: ", r.URL) // 简单的 fmt.PrintF(a ... interface)
if r.ProtoMajor == 2 && strings.Contains(r.Header.Get("Content-Type"), "application/grpc") {
grpcServer.ServeHTTP(w, r)
} else {
otherHandler.ServeHTTP(w, r)
}
})
}
上述代码将运行从mux
连接到http的服务,但不会运行来自gRPC的服务,即不会连接到我的Android设备。
我相信这需要TLS
连接,但我不想实现安全我的Web和Android端代码,因为这将要求我更改Android端和Web的所有代码,我想避免这样做。
因此,我正在寻找一种在不使用任何TLS
配置的情况下将此grpcServer
连接到我的当前serverStruct
的方法。
此外,我还进行了更多的研究:
我还搜索到一个名为cmux
的repo
(Connection Mux),它可以完成同样的工作,但我不明白如何将其与我的当前serverStruct
一起使用,因为我有一个完全功能的Web应用程序正在运行,我只需要在其中添加gRPC
。
英文:
I have recently started working in <b>golang</b> for a project, where I have to use gRPC for push notification on my server to connect to an Android device.
I have created a simple multiplexer mux := http.NewServeMux()
which is working fine with my server code:
serverWeb := http.Server{
Addr: constants.ServerIPWeb,
//Handler: grpcHandlerFunc(grpcServer, mux),
Handler: mux,
}
serverWeb.ListenAndServe()
As from the examples on <a href="https://grpc.io/">gRPC.io</a> I have also created a simple gRPC client/server as a standalone project connected to my android device, with out any TLS
configuration and its working fine.
type server struct{}
func (s *server) DeviceData(ctx context.Context,req *pb.GetDeviceRequest) (*pb.SetDeviceResponse, error){
util.P("Device is: ",req) // simple fmt.PrintF(a ... interface)
return &pb.SetDeviceResponse{Message:"Success"}, nil
}
func main(){
lis, err := net.Listen("tcp", ":8080")
if err!=nil{
log.Fatalf("Failed to listen: %v", err)
}
s := grpc.NewServer()
pb.RegisterDeviceInfoServer(s,&server{})
reflection.Register(s)
if err := s.Serve(lis); err != nil{
log.Fatalf("Falied to server: %v", err)
}
}
The <b>problem</b> is I could not connect my current gRPC server to my serverStruct above. I have tried to add Handler: grpcHandlerFunc(grpcServer, mux)
that will connect my server to the following code, as explained here (<a href="https://grpc.io/blog/coreos"> gRPC with open API </a>)
func grpcHandlerFunc(grpcServer *grpc.Server, otherHandler http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// TODO(tamird): point to merged gRPC code rather than a PR.
// This is a partial recreation of gRPC's internal checks https://github.com/grpc/grpc-go/pull/514/files#diff-95e9a25b738459a2d3030e1e6fa2a718R61
util.P("ResponseFunction: GRPC: ",r.URL) // simple fmt.PrintF(a ... interface)
if r.ProtoMajor == 2 && strings.Contains(r.Header.Get("Content-Type"), "application/grpc") {
grpcServer.ServeHTTP(w, r)
} else {
otherHandler.ServeHTTP(w, r)
}
})
}
The above code will run my Service running from my mux
i.e connecting to http, but it won't run services from gRPC, i.e is connecting to my Android Device.
I believe it requires, TLS
connection, but I don't want to get into the implementation of securing my web and Android side code, as that would require me to change all the code at my Android Side and Web, which I want to avoid.
So I am looking for a way to connect this grpcServer
to my current serverStruct
without using any TLS
configuration.
<b>More Over myResearcH:</b>
I have also searched there is a repo
called cmux
(<a href="https://github.com/soheilhy/cmux">Connection Mux</a>) which will do the same job, but I don't understand how would I use it with my current serverStruct
, as I have a fully functional web app running on this, and I just need to add gRPC
with my current code.
答案1
得分: 1
gRPC服务
可以通过使用Go协程而无需实现TLS
来实现。<br /><br />
<b>创建一个函数,用于提供gRPC服务</b>
func RunGRPC() {
grpcServer := grpc.NewServer()
pb.RegisterGlassInfoServer(grpcServer,&GlassApkBean{})
pb.RegisterDeviceInfoServer(grpcServer, &DeviceInfoBean{}) // 用于多个服务
lis, err := net.Listen("tcp", ":50051")
if err !=nil{
log.Fatalf("错误: %v\n" , err.Error())
}
grpcServer.Serve(lis)
}
<b>使用此函数接收客户端请求</b>
func main(){
.
. // 你的代码
.
go RunGRPC() // 在Go协程中运行gRPC服务器的代码
serverWeb := http.Server{
Addr: "localhost:8080",
Handler: mux,
}
serverWeb.ListenAndServe()
}
英文:
gRPC Service
can be achieved with out the implementation of TLS
by using go routines.<br /><br />
<b>Create a Function, Serving your gRPC</b>
func RunGRPC() {
grpcServer := grpc.NewServer()
pb.RegisterGlassInfoServer(grpcServer,&GlassApkBean{})
pb.RegisterDeviceInfoServer(grpcServer, &DeviceInfoBean{}) // for multiple services
lis, err := net.Listen("tcp", ":50051")
if err !=nil{
log.Fatalf("Error: %v\n" , err.Error())
}
grpcServer.Serve(lis)
}
<b> use this function, to recive client request</b>
func main(){
.
. // Your Code
.
go RunGRPC() // code to run grpc server in go routine.
serverWeb := http.Server{
Addr: "localhost:8080",
Handler: mux,
}
serverWeb.ListenAndServe()
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论