【问题标题】:Call Go RPC socket methods in PHP在 PHP 中调用 Go RPC 套接字方法
【发布时间】:2017-07-02 16:42:29
【问题描述】:

我开始寻找 RPC 框架并找到了 gRPC,但我的问题是它使用了 Protocol-Buffer,我担心如果我想在我当前的单体 PHP 应用程序中使用它会很麻烦。因此,我开始实现一个 Go 基本 RPC 服务,但目前我不知道在 PHP 中使用什么以及如何使用它。

所以基本上我有一个数据库管理器包,其中有这些结构和方法:

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

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

我在互联网上找到this,这是为了实现我想要的相同,但是我试图根据我的需要重写它,但它不起作用。基本上我只是将 callRPC 参数更改如下:

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

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

【问题讨论】:

    标签: php sockets go rpc


    【解决方案1】:

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

    【讨论】:

    • 是的,我们使用的是 RabbitMQ,但我现在才知道它有 RPC 支持,这个性能好吗?
    • RabbitMQ 只是一个消息代理,但您可以通过创建通道、侦听通道并发送以某种格式编码的消息(两种语言中最简单的是 json)来用作 RPC
    猜你喜欢
    • 2015-07-09
    • 1970-01-01
    • 2013-12-21
    • 1970-01-01
    • 1970-01-01
    • 2012-02-13
    • 2012-02-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多