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

时间:2017-02-14 11:47:30

标签: php sockets go rpc

我开始寻找RPC框架,我找到了gRPC,但是我的问题是它使用了Protocol-Buffer,我担心如果我想在我目前的单片PHP应用程序中使用它,那将是一个很大的混乱。所以,我开始实现Go基本RPC服务,但目前我不知道在PHP中使用它是什么以及如何使用它。

所以基本上我有一个databasemanager包,我有这些结构和方法:

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
}

我正在使用启动服务器进行收听的命令:

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
}

所以基本上它是使用一种非常基本的方法。请求和响应格式将是JSON,因为大多数时候它将处理大量数据。

Golang中的客户端看起来像:

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))
}

它运行良好,我可以使用它,但提到我有一个旧的monolitic PHP,我也想在那里使用这些方法。

我在互联网上发现了this,这是为了实现我想要的相同,但问题是我试图根据我的需要重写它,但它没有用。基本上我只是将callRPC参数改为:

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

我不知道,我是否采取了良好的方法?或不?也许有人可以向我展示更好的解决方案。

1 个答案:

答案 0 :(得分:2)

Go rpc默认实现net/rpc使用特定于Go结构的特定编码Gob。据我所知,没有为PHP编写/解除Gob的实现,因此你无法从PHP调用rpc golang服务器。
替代方案是:使用grpc(是的,它使用proto缓冲区,但并不困难,因为proto缓冲区3有新类型的对象)或使用消息代理,如ZeroMQRabbitMQ(如果你我建议使用RabbitMQ,因为它更容易学习)。