OBSERVAÇÃO:este site foi descontinuado. O site será desativado após 31 de janeiro de 2023, e o tráfego será redirecionado para o novo site em https://protobuf.dev. Enquanto isso, as atualizações serão feitas apenas para protobuf.dev.

serviço.h

Mantenha tudo organizado com as coleções Salve e categorize o conteúdo com base nas suas preferências.

#include <google/protobuf/service.h>
namespace google::protobuf

DESCONTINUADO: este módulo declara as interfaces abstratas subjacentes aos serviços de RPC proto2.

Eles são independentes de qualquer implementação de RPC específica. Assim, os serviços proto2 podem ser usados sobre diversas implementações. A partir da versão 2.3.0, as implementações de RPC não devem tentar se basear nelas. Em vez disso, devem fornecer plug-ins de gerador de código que gerem código específico para a implementação de RPC específica. Dessa forma, o código gerado pode ser mais apropriado para a implementação em uso e evitar camadas desnecessárias de indireção.

Quando você usa o compilador de protocolo para compilar uma definição de serviço, ele gera duas classes: uma interface abstrata para o serviço (com métodos que correspondem à definição de serviço) e uma implementação de "stub". Um stub é apenas um wrapper com segurança de tipo em torno de um RpcChannel que emula uma implementação local do serviço.

Por exemplo, a definição do serviço:

service MyService {
  rpc Foo(MyRequest) returns(MyResponse);
}

gerará a interface abstrata "MyService" e a classe "MyService::Stub". Você pode implementar um MyService da seguinte maneira:

class MyServiceImpl : public MyService {
 public:
  MyServiceImpl() {}
  ~MyServiceImpl() {}

  // implements MyService ---------------------------------------

  void Foo(google::protobuf::RpcController* controller,
           const MyRequest* request,
           MyResponse* response,
           Closure* done) {
    // ... read request and fill in response ...
    done->Run();
  }
};

Em seguida, você registra uma instância do MyServiceImpl com a implementação do servidor RPC. Como fazer isso depende da implementação.

Para chamar um MyServiceImpl remoto, você precisa primeiro conectar um RpcChannel a ele. A construção de um canal depende novamente da implementação da RPC. Aqui, usamos um "MyRpcChannel" hipotético como um exemplo:

MyRpcChannel channel("rpc:hostname:1234/myservice");
MyRpcController controller;
MyServiceImpl::Stub stub(&channel);
FooRequest request;
FooResponse response;

// ... fill in request ...

stub.Foo(&controller, request, &response, NewCallback(HandleResponse));

Segurança da linha de execução:

Diferentes implementações de RPC podem fazer garantias diferentes das linhas de execução em que podem executar callbacks e das linhas de execução que o aplicativo pode usar para chamar o sistema de RPC. O software portátil deve estar pronto para callbacks serem chamados em qualquer linha de execução, mas não deve tentar chamar o sistema de RPC de qualquer linha de execução, exceto aquelas em que receberam os callbacks. De maneira realista, no entanto, um software simples provavelmente vai usar um sistema de RPC de uma só linha de execução, enquanto um software sofisticado vai querer usar várias linhas de execução. As implementações de RPC devem fornecer várias opções.

Turmas neste arquivo

Interface base abstrata para serviços de RPC baseados em buffer de protocolo.
Um RpcController faz a mediação de uma única chamada de método.
Interface abstrata de um canal de RPC.

classe Service

#include <google/protobuf/service.h>
namespace google::protobuf

Interface base abstrata para serviços de RPC baseados em buffer de protocolo.

Os serviços em si são interfaces abstratas (implementadas por servidores ou como stubs), mas incluem subclasses nessa interface base. Os métodos dessa interface podem ser usados para chamar os métodos do serviço sem saber o tipo exato dele no momento da compilação (semelhante a Reflection).

Participantes

enum
ChannelOwnership
Ao criar um stub, você pode transmitir STUB_OWNS_CHANNEL como o segundo parâmetro para o construtor para dizer a ele para excluir RpcChannel quando ele for destruído. mais...
Service()
virtual
~Service()
virtual const ServiceDescriptor *
GetDescriptor() = 0
Consiga o ServiceDescriptor que descreve esse serviço e os métodos dele.
virtual void
CallMethod(const MethodDescriptor * method, RpcController * controller, const Message * request, Message * response, Closure * done) = 0
Chame um método do serviço especificado por MethodDescriptor. mais...
virtual const Message &
GetRequestPrototype(const MethodDescriptor * method) const = 0
O CallMethod() exige que a solicitação e a resposta transmitida sejam de uma subclasse específica de Message. mais...
virtual const Message &
GetResponsePrototype(const MethodDescriptor * method) const = 0

enum Service::ChannelOwnership {
  STUB_OWNS_CHANNEL,
  STUB_DOESNT_OWN_CHANNEL
}

Ao criar um stub, você pode transmitir STUB_OWNS_CHANNEL como o segundo parâmetro para o construtor para dizer a ele para excluir RpcChannel quando ele for destruído.

STUB_OWNS_CHANNEL
STUB_DOESNT_OWN_CHANNEL

virtual void Service::CallMethod(
        const MethodDescriptor * method,
        RpcController * controller,
        const Message * request,
        Message * response,
        Closure * done) = 0

Chame um método do serviço especificado por MethodDescriptor.

Isso normalmente é implementado como um switch() simples que chama as definições padrão dos métodos do serviço.

Condições prévias:

  • method->service() == GetDescriptor()
  • solicitação e resposta são da mesma classe que os objetos retornados por GetRequestPrototype(method) e GetResponsePrototype(method).
  • Depois que a chamada for iniciada, não será possível modificar a solicitação e acessar a resposta até que "done" seja chamado.
  • "controller" é do tipo correto para a implementação de RPC que está sendo usada por este Service. Para stubs, o "tipo correto" depende do RpcChannel que o stub está usando. As implementações de Serviço do servidor precisam aceitar qualquer tipo de RpcController que a implementação de RPC do lado do servidor usa.

Pós-condições:

  • "done" será chamado quando o método for concluído. Isso pode ocorrer antes de retornar CallMethod() ou em algum momento no futuro.
  • Se a RPC foi bem-sucedida, "resposta" contém a resposta retornada pelo servidor.
  • Se a RPC falhar, o conteúdo da "response" será indefinido. O RpcController pode ser consultado para determinar se um erro ocorreu e possivelmente receber mais informações sobre o erro.

virtual const Message & Service::GetRequestPrototype(
        const MethodDescriptor * method) const = 0

O CallMethod() exige que a solicitação e a resposta transmitida sejam de uma subclasse específica de Message.

GetRequestPrototype() e GetResponsePrototype() recebem as instâncias padrão desses tipos obrigatórios. Em seguida, chame Message::New() nessas instâncias para criar objetos mutáveis que podem ser transmitidos para CallMethod().

Exemplo:

const MethodDescriptor* method =
  service->GetDescriptor()->FindMethodByName("Foo");
Message* request  = stub->GetRequestPrototype (method)->New();
Message* response = stub->GetResponsePrototype(method)->New();
request->ParseFromString(input);
service->CallMethod(method, *request, response, callback);

classe RpcController

#include <google/protobuf/service.h>
namespace google::protobuf

Um RpcController faz a mediação de uma única chamada de método.

O principal objetivo do controlador é oferecer uma maneira de manipular configurações específicas da implementação da RPC e descobrir erros no nível da RPC.

Os métodos fornecidos pela interface RpcController devem ser um conjunto de recursos "menos comuns comuns" esperados para todas as implementações. Implementações específicas podem oferecer recursos mais avançados (por exemplo, propagação de prazo).

Participantes

RpcController()
virtual
~RpcController()

Métodos do lado do cliente

Essas chamadas podem ser feitas apenas pelo cliente. Os resultados são indefinidos no servidor (pode falhar).
virtual void
Reset() = 0
Redefine o RpcController para o estado inicial, para que possa ser reutilizado em uma nova chamada. mais...
virtual bool
Failed() const = 0
Após a conclusão de uma chamada, ela retorna "true" se a chamada falhar. mais…
virtual std::string
ErrorText() const = 0
Se Failed() for verdadeiro, retornará uma descrição legível do erro.
virtual void
StartCancel() = 0
Aconselha o sistema de RPC que o autor da chamada quer que a chamada de RPC seja cancelada. mais…

Métodos do lado do servidor

Essas chamadas podem ser feitas apenas do lado do servidor.

Os resultados são indefinidos no lado do cliente (pode falhar).

virtual void
SetFailed(const std::string & reason) = 0
Faz com que Failed() retorne verdadeiro no lado do cliente. mais...
virtual bool
IsCanceled() const = 0
Se verdadeiro, indica que o cliente cancelou a RPC, então o servidor também pode desistir de responder. mais…
virtual void
NotifyOnCancel(Closure * callback) = 0
Solicita que o callback fornecido seja chamado quando a RPC é cancelada. mais…

virtual void RpcController::Reset() = 0

Redefine o RpcController para o estado inicial, para que possa ser reutilizado em uma nova chamada.

Não pode ser chamado enquanto uma RPC está em andamento.


virtual bool RpcController::Failed() const = 0

Após a conclusão de uma chamada, ela retorna "true" se a chamada falhar.

Os possíveis motivos de falha dependem da implementação da RPC. Failed() não pode ser chamado antes do término de uma chamada. Se Failed() retornar verdadeiro, o conteúdo da mensagem de resposta será indefinido.


virtual void RpcController::StartCancel() = 0

Aconselha o sistema de RPC que o autor da chamada quer que a chamada de RPC seja cancelada.

O sistema de RPC pode cancelar a chamada imediatamente, aguardar um pouco e depois cancelá-la. Se a chamada for cancelada, o callback "done" ainda será chamado, e o RpcController vai indicar que a chamada falhou naquele momento.


virtual void RpcController::SetFailed(
        const std::string & reason) = 0

Faz com que Failed() retorne verdadeiro no lado do cliente.

O "motivo" será incorporado à mensagem retornada por ErrorText(). Se você precisar retornar informações legíveis por máquina sobre falhas, incorpore-as ao buffer de protocolo de resposta e NÃO chame SetFailed().


virtual bool RpcController::IsCanceled() const = 0

Se verdadeiro, indica que o cliente cancelou a RPC, então o servidor também pode desistir de responder.

O servidor ainda precisa chamar o callback "done" final.


virtual void RpcController::NotifyOnCancel(
        Closure * callback) = 0

Solicita que o callback fornecido seja chamado quando a RPC é cancelada.

O callback vai ser sempre chamado uma única vez. Se a RPC for concluída sem ser cancelada, o callback será chamado após a conclusão. Se o RPC já tiver sido cancelado quando NotificarOnCancel() for chamado, o callback será chamado imediatamente.

NotificationOnCancel() não pode ser chamado mais de uma vez por solicitação.

classe RpcChannel

#include <google/protobuf/service.h>
namespace google::protobuf

Interface abstrata de um canal de RPC.

Um RpcChannel representa uma linha de comunicação com o Service, que pode ser usada para chamar os métodos do Service. O serviço pode estar em execução em outra máquina. Normalmente, não chame um RpcChannel diretamente, mas sim construindo um stub de stub. Exemplo:

RpcChannel* channel = new MyRpcChannel("remotehost.example.com:1234");
MyService* service = new MyService::Stub(channel);
service->MyMethod(request, &response, callback);

Participantes

RpcChannel()
virtual
~RpcChannel()
virtual void
CallMethod(const MethodDescriptor * method, RpcController * controller, const Message * request, Message * response, Closure * done) = 0
Chame o método fornecido do serviço remoto. mais…

virtual void RpcChannel::CallMethod(
        const MethodDescriptor * method,
        RpcController * controller,
        const Message * request,
        Message * response,
        Closure * done) = 0

Chame o método fornecido do serviço remoto.

A assinatura desse procedimento parece a mesma que Service::CallMethod(), mas os requisitos são menos rigorosos de maneira importante: os objetos de solicitação e resposta não precisam ser de uma classe específica, desde que os descritores sejam method->input_type() e method->output_type().