Я не могу отправить запрос от xamarin, но могу отправить запрос из приложения WPF - PullRequest
1 голос
/ 16 февраля 2020

Я пытаюсь отправить запрос из android в службу gRP C. С приложением ядра WPF net, работающим на том же компьютере, оно работает, но с android оно не работает. Также я пробовал это приложение WPF на другом компьютере (на виртуальной машине), и оно тоже отлично работает.

Код моего приложения xamarion:

private void SetVariablesServicio()
{
    _serviceAddress = "http://1.2.3.4:5001";

    using (StreamReader miCertificado = new StreamReader(Assets.Open("CA.crt")))
    {
        _caCertificate = miCertificado.ReadToEnd();
    }

    using (StreamReader miCertificado = new StreamReader(Assets.Open("Client.crt")))
    {
        _clientCertificate = miCertificado.ReadToEnd();
    }

    using (StreamReader miCertificado = new StreamReader(Assets.Open("Client.key")))
    {
        _clientPrivateKey = miCertificado.ReadToEnd();
    }
}



private async void btnTestServicio_Click()
{
    try
    {
        GrpcClient.GestorAplicaciones miGrpcClient = new GrpcClient.GestorAplicaciones(_serviceAddress, _caCertificate, _clientCertificate, _clientPrivateKey);

        string miSaludo = await miGrpcClient.PingAsync("Álvaro");

        ShowAlert("Error", miSaludo);
    }
    catch (Exception ex)
    {
        ShowAlert("Error", ex.Message);
    }
}

Общая библиотека для gRP C клиенты:

public class GestorAplicaciones
    {
        #region constructor
        public GestorAplicaciones(string paramAddressService, string paramStrCertificadoCa, string paramStrCertificadoCliente, string paramStrClaveCertificadoCliente)
        {
            _serviceAddress = paramAddressService;
            _caCertificate = paramStrCertificadoCa;
            _clientCertificate = paramStrCertificadoCliente;
            _clientPrivateKey = paramStrClaveCertificadoCliente;
        }
        #endregion constructor


        #region variables de clase
        private string _serviceAddress;
        private string _caCertificate;
        private string _clientPrivateKey;
        private string _clientCertificate;
        #endregion variables de clase



        #region método de llamada al servicio
        public async Task<string> PingAsync(string paramStrNombreLlamante)
        {

            Gestor.GestorClient miClienteGrpc = GetClient();




            PingRequest input = new PingRequest { NomreLlamante = paramStrNombreLlamante };
            var reply = await miClienteGrpc.PingAsync(input);




            return reply.MensajeRespuesta;
        }



        private Gestor.GestorClient GetClient()
        {
            var httpClientHandler = new System.Net.Http.HttpClientHandler();
            httpClientHandler.ServerCertificateCustomValidationCallback =
                System.Net.Http.HttpClientHandler.DangerousAcceptAnyServerCertificateValidator;
            var httpClient = new System.Net.Http.HttpClient(httpClientHandler);
            var channel = GrpcChannel.ForAddress(_serviceAddress,
                new GrpcChannelOptions { HttpClient = httpClient });
            var client = new Gestor.GestorClient(channel);





            return client;
        }

Клиент WPF:

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();


        _serviceAddress = "https://1.2.3.4:5001";
        _caCertificate = System.IO.File.ReadAllText("certificados/ca.crt");
        _clientPrivateKey = System.IO.File.ReadAllText("certificados/client.key");
        _clientCertificate = System.IO.File.ReadAllText("certificados/client.crt");
    }



    #region variables de clase
    private readonly string _serviceAddress;

    private readonly string _caCertificate;
    private readonly string _clientPrivateKey;
    private readonly string _clientCertificate;
    #endregion variables de clase



    private async void Button_Click(object sender, RoutedEventArgs e)
    {
        try
        {
            GrpcClient.GestorAplicaciones miGrpcClient = new GrpcClient.GestorAplicaciones(_serviceAddress, _caCertificate, _clientCertificate, _clientPrivateKey);

            string miSaludo = await miGrpcClient.PingAsync("Álvaro");

            MessageBox.Show(miSaludo);
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message);
        }
    }
}

Служба:

public class Program
{
    public static void Main(string[] args)
    {
        CreateHostBuilder(args).Build().Run();
    }

    // Additional configuration is required to successfully run gRPC on macOS.
    // For instructions on how to configure Kestrel and gRPC clients on macOS, visit https://go.microsoft.com/fwlink/?linkid=2099682
    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.ConfigureKestrel(options =>
                {
                    //NOTA: se tiene que poner la IP porque si no, se dice que el equipo remoto ha denegado la conexión.
                    options.Listen(miAddress, 5001, o =>
                    {
                        o.Protocols = HttpProtocols.Http2;
                        o.UseHttps(@"certificados\service.pfx", "123456");
                    });
                })


                .ConfigureLogging(logging =>
                 {
                     logging.AddFilter("Grpc", LogLevel.Debug);
                 });

                webBuilder.UseStartup<Startup>();
            });
}

Моя идея состоит в том, чтобы иметь общую библиотеку для клиентской стороны, которые могут использоваться клиентами xamarin и wpf.

Я отлаживаю приложение xamarion, развертывающее его на телефоне android.

Почему запрос работает из приложения WPF, а не из приложения WPF Приложение xamarin?

Спасибо.

1 Ответ

1 голос
/ 24 февраля 2020

Grp c. Net не работает на Xamarin, потому что, похоже, существует проблема с отправкой http2 traffi c через System. Net .Http.HttpClientHandler на monodroid.

Что вы можете сделать, добавить зависимость к Grp c .Core nuget и создать клиент GRP c через него. Остальная часть API в значительной степени используется совместно (nuget Grp c .Core.Api совместно используется обеими библиотеками).

// For secured grpc service
var channel = new Channel("1.2.3.4:5001", new SslCredentials());
// cleartext
var channel = new Channel("1.2.3.4:5001", ChannelCredentials.Insecure);

Пожалуйста, сделайте свое собственное исследование о том, как создать экземпляр ChannelCredentials. Вышеупомянутый код работает для меня, но я не уверен, работает ли он для всех сценариев ios.

. Вы можете удалить зависимость nuget Grp c. Net .Client. Обязательно добавьте в проект Xamarin. Android зависимость Grp c .Core.

Причина, по которой работает Grp c .Core, заключается в том, что он является управляемой оболочкой для основной группы GRP. c клиентская библиотека, написанная на с ++. Поэтому он не полагается на поддержку Http от mono / .net.

. Для меня не только Grp c, но и любой запрос Http2 завершается неудачно на xamarin android из-за этой проблемы. Почему Xamarin Android не может отправить запросы GRPC / Http2?

...