dqyz48470 2017-02-14 11:47
浏览 130
已采纳

在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 2017-02-14 12:03
    关注

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

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 如何让企业微信机器人实现消息汇总整合
  • ¥50 关于#ui#的问题:做yolov8的ui界面出现的问题
  • ¥15 如何用Python爬取各高校教师公开的教育和工作经历
  • ¥15 TLE9879QXA40 电机驱动
  • ¥20 对于工程问题的非线性数学模型进行线性化
  • ¥15 Mirare PLUS 进行密钥认证?(详解)
  • ¥15 物体双站RCS和其组成阵列后的双站RCS关系验证
  • ¥20 想用ollama做一个自己的AI数据库
  • ¥15 关于qualoth编辑及缝合服装领子的问题解决方案探寻
  • ¥15 请问怎么才能复现这样的图呀