背景

有时候,我们在python中实现了一个功能,这功能如果用golang重新写呢,会比较麻烦,如果要在golang中调用python中的功能。 方式有很多,主要就是两个程序如果沟通的问题,那方式就各种各样了,可以通过http协议,json/xml等格式,或者tcp, 当然还有个 选择就是gRPC

python 实现 rpc server

这个网上资料比较多,通过protobuf生成代码,实现server端的功能。

golang 实现 rpc client

同样的,根据proto文件,生成go code, 可以通过client连接rpc server

目前的一个小实现

  • 主要功能用python实现,同时python实现了 rpc server功能,在gin里面,通过client来调用
package main

import (
        "context"
        "fmt"
        "io/ioutil"
        "log"
        "net/http"
        "os"
        "path/filepath"

        pb "github.ibm.com/assetharvest/text-detection-tf/proto"

        "github.com/gin-gonic/gin"
        "google.golang.org/grpc"
)

const (
        address = "localhost:50501"
)

func main() {

        r := gin.Default()
        r.GET("/ping", func(c *gin.Context) {
                c.JSON(200, gin.H{
                        "message": "pong",
                })
        })
        r.POST("/", func(c *gin.Context) {
                // single file
                file, err := c.FormFile("file")
                                if err != nil {
                        c.String(http.StatusBadRequest, fmt.Sprintf("get form err: %s", err.Error()))
                        return
                }
                filename := filepath.Base(file.Filename)

                // create temp directory
                dname, err := ioutil.TempDir("", "textdetector")
                if err != nil {
                        c.String(http.StatusBadRequest, fmt.Sprintf("get form err: %s", err.Error()))
                        return
                }
                defer os.RemoveAll(dname)

                fname := filepath.Join(dname, filename)

                // Upload the file to specific dst.
                c.SaveUploadedFile(file, fname)

                conn, err := grpc.Dial(address, grpc.WithInsecure())
                if err != nil {
                        log.Fatalf("did not connect: %v", err)
                }
                defer conn.Close()
                client := pb.NewTextDetecterClient(conn)

                // Contact the server and print out its response.
                r, err := client.TextDetect(context.Background(), &pb.TextDetectRequest{Filename: fname})
                if err != nil {
                        log.Fatalf("could not connect: %v", err)
                }
                log.Printf("%+v\n", r.Result)
                // c.JSON(200, r.Result)
                c.Writer.Header().Set("Content-Type", "application/json")
                c.Writer.WriteHeader(200)
                c.Writer.WriteString(r.Result)
        })

        r.Run(":3000")
}