首页 > 解决方案 > 让 http.handleFunc() 在 gRPC 服务器上工作

问题描述

所以我试图让一个在 GOlang 中运行的小型 gRPC 应用程序。gPRC 命令可以正常工作,但是,我还希望能够从 URL 与我的数据库进行交互。在我添加 gRPC 服务器之前,它运行良好,但是在 gRPC 服务器或“正常”服务器被阻塞并且无法启动之后。有没有办法既拥有 gRPC 接口又能够从 URL 进行调用?

我的服务器代码:

func main(){
    createItem("test", "test")
    http.HandleFunc("/get/", get)
    http.HandleFunc("/set/", set)
    listener, err := net.Listen("tcp", ":4000")
    if err != nil{
        log.Fatal("Listener error: ", err)
    }
    s := grpc.NewServer()
    pb.RegisterGetSetServiceServer(s, &server{})
    reflection.Register(s)
    s.Serve(listener)


    log.Printf("serving rpc on port %d", 4000)
    err = http.Serve(listener, nil)
    if err != nil{
        log.Fatal("error serving: ", err)
    }

}

func (s *server) Get(ctx Context, req *pb.GetRequest) (*pb.Response, error) {
    var body string
    log.Printf("Recived: %v", req.GetTitle())
    for _, val := range database{
        if req.GetTitle() == val.Title{
            body = val.Body
            return &pb.Response{Body:body}, nil
        }
    }
    return &pb.Response{Body:"Nothing found"}, nil

}
func get(writer http.ResponseWriter, req *http.Request ){
    var value string


    v := req.FormValue("key")
    for _, val := range database{
        if val.Title == v {
              value = val.Body
        }
    }
    fmt.Fprintln(writer,  value)
}

标签: go

解决方案


正如 Mark 在评论中所说,您可以在 Go HTTP 服务器中提供 gRPC。的文档ServeHTTP有一个解释:

https://godoc.org/google.golang.org/grpc#Server.ServeHTTP

但是,gRPC-Go 团队不建议或支持这样做,因为它不允许某些 gRPC 功能工作(例如 Keepalives)。相反,我们建议使用不同的端口,或者使用类似的东西,cmux这样您就可以运行完整的 gRPC 服务器以及单独的 HTTP 服务器:

https://github.com/soheilhy/cmux


推荐阅读