Я начал искать RPC-фреймворки и нашел gRPC, но моя проблема в том, что он использует Protocol-Buffer, и я боюсь, что если я захочу использовать его в моем текущем монолитном PHP-приложении, это будет большой беспорядок. Итак, я начал реализовывать базовый RPC-сервис Go, но в настоящее время я понятия не имею, что и как использовать в 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, потому что большую часть времени он будет обрабатывать большие объемы данных.
Клиент в Голанге выглядит так:
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, где я тоже хочу использовать методы там.
я нашел этот в интернете, который должен реализовать то же, что я хочу, но проблема, которую я пытался переписать для моих нужд, но она не работает. В основном я просто изменил параметры callRPC следующим образом:
$result = callRPC(
"tcp://127.0.0.1:50051",
[
'{"method":"DatabaseManager.Last","params":["asd"],"id":0}',
],
1,
8
);
Я не знаю, следую ли я хорошему подходу? Или нет? Может быть, кто-то может показать мне лучшее решение.
Реализация по умолчанию Go rpc net/rpc
использовать определенную кодировку, специфичную для структуры Go, которая называется плевок. Насколько я знаю, нет реализации кодирования / декондинга Gob для PHP, и по этой причине вы не сможете вызвать сервер rpc golang из PHP.
Альтернативы: используйте grpc (да, он использует протобуфер, но это не сложно, и поскольку в прото-буфере 3 появился новый тип объекта) или используйте посредник сообщений, такой как ZeroMQ или же RabbitMQ (если вы новичок в обоих случаях, я предлагаю RabbitMQ, так как его легче освоить).
Других решений пока нет …