dqyz48470
dqyz48470
2017-02-14 11:47

在PHP中调用Go RPC套接字方法

已采纳

I started looking for RPC frameworks and I found the gRPC, but my problem it uses the Protocol-Buffer and I'm afraid if I want to use it in my current monolithic PHP application it will be a big mess. So, I started to implement a Go basic RPC service but currently I don't have any idea what and how to use it in PHP.

So basically I have a databasemanager package where I have these struct and methods:

type DatabaseManager struct {
    Database *gorm.DB
    Log      logging.Logger
}

func (db *DatabaseManager) Last(args *string, reply *string) error {

    db.Log[logging.INFO].Printf("%v", *args)
    reply = args
    db.Log[logging.INFO].Printf("%v", *reply)
    return nil
}

And I'm using a command which starts the server for listening:

func registerDatabaseManager(server *rpc.Server, dbManager *databasemanager.DatabaseManager) {
    server.RegisterName("DatabaseManager", dbManager)
}

func RunRPC(path string) error {
    db, _, log := dependencyInjection(path)
    dbManager := &databasemanager.DatabaseManager{
        Database: db,
        Log:      log,
    }
    server := rpc.NewServer()
    registerDatabaseManager(server, dbManager)
    listen, err := net.Listen("tcp", ":50051")
    if err != nil {
        log[logging.ERROR].Print(err)
    }
    log[logging.INFO].Print("Server started - listening on :50051")
    server.Accept(listen)
    return nil
}

So basically it is using a very basic approach. The request and response format will be JSON because most of the time it will handle big amounts of data.

The client in Golang is looks like:

type DBManager struct {
    client *rpc.Client
}

func (t *DBManager) Last(args *string) string {
    *args = "awesome test"
    var reply string
    err := t.client.Call("DatabaseManager.Last", args, &reply)
    if err != nil {
        log.Fatal("arith error:", err)
    }
    return reply
}

func main() {
    conn, err := net.Dial("tcp", "localhost:50051")
    if err != nil {log.Fatal("Connectiong:", err)}
    dbManager := &DBManager{client: rpc.NewClient(conn)}
    asd := "asdasqwesaf"
    fmt.Println(dbManager.Last(&asd))
}

It is working nicely and I can use it but had mentioned I have an old monolitic PHP where I want to use the methods there too.

I found this on the internet, which is to implement the same what I want, but the problem I tried to rewrite it for my needs, but it's not working. Basically I just changed the callRPC params as the following:

$result = callRPC(
    "tcp://127.0.0.1:50051",
    [
        '{"method":"DatabaseManager.Last","params":["asd"],"id":0}',
    ],
    1,
    8
); 

I don't know, am I following a good approach? Or not? Maybe someone can show me a better solution.

  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 复制链接分享
  • 邀请回答

1条回答

  • doupao6011 doupao6011 4年前

    The Go rpc default implementation net/rpc use a particular encoding specific for Go struct called Gob. Far as I know there isn't a implementation of encoding/deconding Gob for PHP and for this reason you will not able to call an rpc golang server from PHP.
    The alternatives are: use grpc (yes, it use proto buffer but is not to difficult and since proto buffer 3 there new type of object) or use a message broker such as ZeroMQ or RabbitMQ (if you are beginner on both I suggest RabbitMQ since it's more easier to learn).

    点赞 评论 复制链接分享

相关推荐