簡體   English   中英

如何在 Xamarin.Forms 上調用 HTTP2

[英]How to make calls to HTTP2 on Xamarin.Forms

帶有 .Net Standart 2.0 的 Xamarin.Forms 的 gRpc 適用於 http2,因此它應該是進行 HttpClient 調用或重用現有 gRpc 功能的某種方式。 可能是我錯過了什么。

重現問題的示例應用程序。 您需要在某處托管 gRpc 服務。 WebClient 調用在 AboutPage.xaml.cs aslo 測試項目中,在 web 文件夾中有 asp core 3.1。 XamarinHttp2WithBackend · GitHub

Fallowing instructions Microsoft.com - HttpClient Stack and SSL/TLS Implementation Selector for Android and Stackoverflow.com - Use HTTP 2 with HttpClient in.Net 也沒有幫助。

對於 Asp Core 3.1 控制台應用程序,您可以執行(如下)並且可以工作。 它不適用於 2.2 及更低版本

AppContext.SetSwitch("System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport", true);

var client = new HttpClient();
var req = new HttpRequestMessage(HttpMethod.Get, $"http://123.123.123.123:1234/ping/")
{
    Version = new Version(2, 0),
};

var response = await client.SendAsync(req);

在 Xamarin 上使用相同會引發異常

 Java.IO.IOException: unexpected end of stream on com.android.okhttp.Address@ce6f1800 ---> Java.IO.EOFException: 
 not found: size=17 content=0000080700000000000000000000000001...
01-23 15:10:13.472 I/MonoDroid(28829):    --- End of inner exception stack trace ---
01-23 15:10:13.472 I/MonoDroid(28829):   at Java.Interop.JniEnvironment+InstanceMethods.CallIntMethod (Java.Interop.JniObjectReference instance, Java.Interop.JniMethodInfo method, Java.Interop.JniArgumentValue* args) [0x0006e] in <e7e2d009b69d4e5f9a00e6ee600b8a8e>:0 
01-23 15:10:13.472 I/MonoDroid(28829):   at Java.Interop.JniPeerMembers+JniInstanceMethods.InvokeVirtualInt32Method (System.String encodedMember, Java.Interop.IJavaPeerable self, Java.Interop.JniArgumentValue* parameters) [0x0002a] in <e7e2d009b69d4e5f9a00e6ee600b8a8e>:0 
01-23 15:10:13.472 I/MonoDroid(28829):   at Java.Net.HttpURLConnection.get_ResponseCode () [0x0000a] in <d706cf8faf5542949900cf6d57864528>:0 
01-23 15:10:13.472 I/MonoDroid(28829):   at Xamarin.Android.Net.AndroidClientHandler+<>c__DisplayClass46_0.<DoProcessRequest>b__2 () [0x00000] in <d706cf8faf5542949900cf6d57864528>:0 
01-23 15:10:13.472 I/MonoDroid(28829):   at System.Threading.Tasks.Task`1[TResult].InnerInvoke () [0x0000f] in /Users/builder/jenkins/workspace/archive-mono/2019-08/android/release/external/corert/src/System.Private.CoreLib/src/System/Threading/Tasks/Future.cs:534 
01-23 15:10:13.472 I/MonoDroid(28829):   at System.Threading.Tasks.Task.Execute () [0x00000] in /Users/builder/jenkins/workspace/archive-mono/2019-08/android/release/external/corert/src/System.Private.CoreLib/src/System/Threading/Tasks/Task.cs:2319 

DEBUG 的解決方案設置

<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>portable</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug</OutputPath>
<DefineConstants>DEBUG;</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<AndroidLinkMode>None</AndroidLinkMode>
<AotAssemblies>false</AotAssemblies>
<EnableLLVM>false</EnableLLVM>
<AndroidEnableProfiledAot>false</AndroidEnableProfiledAot>
<BundleAssemblies>false</BundleAssemblies>
<AndroidSupportedAbis>
</AndroidSupportedAbis>
<EmbedAssembliesIntoApk>false</EmbedAssembliesIntoApk>
<Debugger>Xamarin</Debugger>
<AndroidUseSharedRuntime>true</AndroidUseSharedRuntime>
<AndroidUseAapt2>false</AndroidUseAapt2>
<AndroidHttpClientHandlerType>Xamarin.Android.Net.AndroidClientHandler</AndroidHttpClientHandlerType>
<AndroidTlsProvider>btls</AndroidTlsProvider>
</PropertyGroup>

我的asp啟動。 我將它與 grp 服務一起使用。 發布為控制台單個可執行文件

public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddGrpc((options => { options.EnableDetailedErrors = true; }));
        services.AddMvc(options => options.EnableEndpointRouting = false);

        //services.AddDbContext<PuvDbContext>();
        services.AddScoped<IAccountService, AccountService>();
        services.AddSingleton<IFirebirdService, FirebirdService>();
        services.AddSingleton<IClassificatorService, ClassificatorService>();
        services.AddSingleton<IClassificatorRepository, ClassificatorRepository>();

        services.AddControllers();
    }

    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }

        app.UseRouting();
        app.UseMvcWithDefaultRoute();

        app.UseStaticFiles();
        app.UseMvc();

        app.UseEndpoints(endpoints =>
        {
            endpoints.MapGrpcService<GreeterService>();
            endpoints.MapGrpcService<AccountController>();
            endpoints.MapGrpcService<ReviewController>();
            endpoints.MapGrpcService<StaticDataController>();
            endpoints.MapGrpcService<TaskController>();
            endpoints.MapControllers();
        });


    }
}

我調用的控制器方法

[Route("files")]
public class FileController : Controller
{
    public FileController()
    {       
    }

    [HttpGet("hi")]
    public async Task<HttpResponseMessage> GetTest()
    {
        return new HttpResponseMessage(HttpStatusCode.OK);
    }
}

有幾種可能的解決方案:

  1. 如果您只是將 Target 框架更新為 .NET Standard 2.1 或更新版本,那么這應該可以解決您的問題。 如果您不能這樣做是因為您的解決方案較舊,請嘗試其余的。 在此處輸入圖像描述
  2. 打開您的 Android 項目選項,然后在“Android build”中,將 HttpClient 實現值更新為“AndroidClientHandler”或任何其他值,然后重試,這已添加到該配置的 CSPROJ 中
<AndroidHttpClientHandlerType>Xamarin.Android.Net.AndroidClientHandler</AndroidHttpClientHandlerType>
<AndroidTlsProvider>btls</AndroidTlsProvider>

然后我只需要在我的 HttpClient 中傳遞這個 HttpClientHandler:

httpClient = new HttpClient(new HttpClientHandler()
{
    UseProxy = true
});
  1. 如果這也不起作用,那么您必須使用這兩個 nuget 包之一 http2dotnet ( https://github.com/Matthias247/http2dotnet ) 或 httptwo ( https://github.com/Redth/HttpTwo ) 而不是在他們的 GitHub 中顯示:
// Uri to request
var uri = new Uri ("http://somesite.com:80/index.html");

// Create a Http2Client
var http2 = new Http2Client (uri);

// Specify any custom headers
var headers = new NameValueCollection ();
headers.Add ("some-header", "value");

// For some requests you may have a request body
byte[] data = null; 

// Await our response
var response = await http2.Send (uri, HttpMethod.Get, headers, data); 

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM