Heim  >  Artikel  >  Backend-Entwicklung  >  GO und GRPC: Protobuff-Klassen „on the fly“ erstellen

GO und GRPC: Protobuff-Klassen „on the fly“ erstellen

PHPz
PHPznach vorne
2024-02-06 11:06:031230Durchsuche

GO 和 GRPC:“在飞行中”创建 protobuff 类

Frageninhalt

Ich bin neu bei GRPC und kann ein Problem nicht lösen. Ist es möglich, eine Protobuff-Datei zu erstellen, wenn die Anwendung bereits ausgeführt wird? Ich erhalte beispielsweise ein json vom Benutzer wie folgt:

"protobuf_file": "protobuf.proto", // File will be also recieved from user
"service_name": "Unary",
"method_name": "GetServerResponse",
"request_data_serializer_name": "MessageRequest",
"body": "grpc_request_data.json", // File will be also recieved from user

Hier habe ich eine .proto-Datei, einen Dienstnamen, eine Methode und eine Nachricht sowie einen weiteren JSON mit Daten zum Füllen der Nachricht. Jetzt muss ich die Verbindung öffnen und die benötigte Methode mit den bereitgestellten Daten aufrufen.

TY!

PS .proto Die Datei (aus der Anleitung zur Beschaffung) lautet:

syntax = "proto3";

package protobuf_all_modes;

service Unary {
 rpc GetServerResponse(MessageRequest) returns (MessageResponse) {}
}

message MessageRequest {
 string message = 1;
}

message MessageResponse {
 string message = 1;
 int32 random_int32 = 2;
}

Das zweite json wird sein:

{
    "message": "hello World!"
}

Ich weiß nicht, wo ich nach einer Lösung suchen soll. Über Vorschläge wäre ich sehr dankbar.


Richtige Antwort


Wenn jemand das gleiche Problem hat, gibt es eine wirklich gute Bibliothek – https://pkg.go.dev/github.com/jhump/[ email protected] /dynamic und ein Unterpakethttps://pkg.go.dev/github. com/jhump/[email protected]/dynamic/grpcdynamic Der Codeausschnitt wäre: parser

func NewGrpcObject(operation *BaseOperation) *GrpcObject {
    fns, err := protoparse.ResolveFilenames([]string{"./"}, operation.ProtoFile) // prase .proto file
    if err != nil {
        log.Error(err)
    }

    parser := protoparse.Parser{}
    fds, err := parser.ParseFiles(fns...)
    if err != nil {
        log.Error(err)
    }
    descriptor := fds[0] // In my case there will be only one .proto
    pkg := descriptor.GetPackage()
    serviceDescriptor := descriptor.FindService(pkg + "." + operation.ServiceName) // name of service descriptor will be with package name first
    methodDescriptor := serviceDescriptor.FindMethodByName(operation.MethodName)
    requestDescriptor := methodDescriptor.GetInputType() // You can get types for request and response
    responseDescriptor := methodDescriptor.GetOutputType()

    return &GrpcObject{
        RequestDesc: requestDescriptor,
        MethodDesc: methodDescriptor,
        ResponseDesc: responseDescriptor,
    }
}

caller

// connect 
        conn, _ := grpc.Dial(operation.Host, grpc.WithTransportCredentials(credentials.NewTLS(c.TLSClientConfig.NewTLSConfig())))
        stub = grpcdynamic.NewStub(conn)

// call
    message := dynamic.NewMessage(operation.GrpcObject.RequestDesc) // from parser
    message.UnmarshalJSON(operation.Body) // here a JSON to fill message

    resp, err := stub.InvokeRpc(ctx, operation.GrpcObject.MethodDesc, message)
    if err != nil {
        // handle err
    }
    respMessage := dynamic.NewMessage(operation.GrpcObject.ResponseDesc) // descriptor from parser
    respMessage.ConvertFrom(resp) // convert message from raw response

Das obige ist der detaillierte Inhalt vonGO und GRPC: Protobuff-Klassen „on the fly“ erstellen. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:stackoverflow.com. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen