Closed m-yukio closed 2 years ago
Looks like the client sent an HTTP/1.1 request to the server. The server is rejecting it because it doesn't start with the HTTP/2 preface.
Unity might not support HTTP/2. I'm not a Unity expert and I'm not sure the right person for you to talk to.
If you comment out the HttpHandler setting in GrpcChannelOptions with the following code
string certPath = System.IO.Path.Combine(Application.streamingAssetsPath, "example.crt");
string keyPath = System.IO.Path.Combine(Application.streamingAssetsPath, "example.key");
string caPath = System.IO.Path.Combine(Application.streamingAssetsPath, "root_ca.crt");
HttpClientHandler handler = new HttpClientHandler();
handler.ServerCertificateCustomValidationCallback = (HttpRequestMessage request, X509Certificate2 certificate, X509Chain certificateChain, SslPolicyErrors policy) =>
{
Debug.Log("handler.ServerCertificateCustomValidationCallback");
return true;
};
handler.ClientCertificates.Add(new X509Certificate2(certPath));
Grpc.Core.ChannelBase channel = GrpcChannel.ForAddress("https://192.168.200.3:50051", new GrpcChannelOptions
{
HttpHandler = handler
});
I got the following error in Unity, so I thought that HTTP / 2 support was possible.
PlatformNotSupportedException: gRPC requires extra configuration on .NET implementations that don't support gRPC over HTTP/2. An HTTP provider must be specified using GrpcChannelOptions.HttpHandler.The configured HTTP provider must either support HTTP/2 or be configured to use gRPC-Web. See https://aka.ms/aspnet/grpc/netstandard for details.
Grpc.Shared.HttpHandlerFactory.CreatePrimaryHandler () (at <93d755b016cc4513ac20ab2598098c88>:0)
Grpc.Net.Client.GrpcChannel.CreateInternalHttpInvoker (System.Net.Http.HttpMessageHandler handler) (at <93d755b016cc4513ac20ab2598098c88>:0)
Grpc.Net.Client.GrpcChannel..ctor (System.Uri address, Grpc.Net.Client.GrpcChannelOptions channelOptions) (at <93d755b016cc4513ac20ab2598098c88>:0)
Grpc.Net.Client.GrpcChannel.ForAddress (System.Uri address, Grpc.Net.Client.GrpcChannelOptions channelOptions) (at <93d755b016cc4513ac20ab2598098c88>:0)
Grpc.Net.Client.GrpcChannel.ForAddress (System.String address, Grpc.Net.Client.GrpcChannelOptions channelOptions) (at <93d755b016cc4513ac20ab2598098c88>:0)
GrpcTest.RunHelloWorld (System.Boolean useNet) (at Assets/Scripts/GrpcTest.cs:70)
GrpcTest.RunNet () (at Assets/Scripts/GrpcTest.cs:23)
UnityEngine.Events.InvokableCall.Invoke () (at /Users/bokken/buildslave/unity/build/Runtime/Export/UnityEvent/UnityEvent.cs:178)
UnityEngine.Events.UnityEvent.Invoke () (at /Users/bokken/buildslave/unity/build/Runtime/Export/UnityEvent/UnityEvent/UnityEvent_0.cs:58)
UnityEngine.UI.Button.Press () (at Library/PackageCache/com.unity.ugui@1.0.0/Runtime/UI/Core/Button.cs:70)
UnityEngine.UI.Button.OnPointerClick (UnityEngine.EventSystems.PointerEventData eventData) (at Library/PackageCache/com.unity.ugui@1.0.0/Runtime/UI/Core/Button.cs:114)
UnityEngine.EventSystems.ExecuteEvents.Execute (UnityEngine.EventSystems.IPointerClickHandler handler, UnityEngine.EventSystems.BaseEventData eventData) (at Library/PackageCache/com.unity.ugui@1.0.0/Runtime/EventSystem/ExecuteEvents.cs:57)
UnityEngine.EventSystems.ExecuteEvents.Execute[T] (UnityEngine.GameObject target, UnityEngine.EventSystems.BaseEventData eventData, UnityEngine.EventSystems.ExecuteEvents+EventFunction`1[T1] functor) (at Library/PackageCache/com.unity.ugui@1.0.0/Runtime/EventSystem/ExecuteEvents.cs:272)
UnityEngine.EventSystems.EventSystem:Update() (at Library/PackageCache/com.unity.ugui@1.0.0/Runtime/EventSystem/EventSystem.cs:501)
I was thinking of setting HttpClientHandler to HttpHandler in GrpcChannelOptions when communicating via HTTP / 2 instead of HTTP / 1.1. Is my understanding wrong?
"The configured HTTP provider must either support HTTP/2 or be configured to use gRPC-Web."
That's the important part from the error message. HttpClientMessageHandler
on that platform - Unity - might not support HTTP/2. Like I said, I'm not a Unity expert.
Thank you.
Found this through Twitter! I have a feeling this issue should be closed since Unity isn't an official dotnet runtime.
@m-yukio you might want to reconsider using a NuGet client directly in Unity,. The client you're referencing (https://github.com/GlitchEnzo/NuGetForUnity) is a user-created thing, and it doesn't seem to have the best support (the original author hasn't contributed in years, CI is constantly broken, install instructions point to a bad link). NuGet is intended for .Net Framework, .Net Core, and .Net applications. Unity's .net runtime isn't one of those; it's a custom fork of mono, so even if a package compiles, the runtime may fail (which is what happened in your case). If you really want a NuGet client in Unity this might be more reliable https://github.com/xoofx/UnityNuGet since it's upm compatible and points to a curated list of NuGet packages that work in Unity, but the server for that is pointing to the author's personal azure instance so you still have to proceed with caution if you're planning on making daily builds. Honestly there just isn't a really reliable way to make NuGet work in Unity; I've talked to the upm devs about this a couple years ago and that was the direction they chose.
If you really want NuGet packages though; I hate to say it but I'd honestly recommend downloading directly off NuGet, then vendor the package into your project, and do lots of testing. Official MS docs are a bit outdated, but they actually recommend this approach (https://docs.microsoft.com/en-us/visualstudio/gamedev/unity/unity-scripting-upgrade#add-packages-from-nuget-to-a-unity-project).
Thank you. Please refer to the contents explained and try it.
I confirmed it with Wireshark, but it seems that it is not communicating with HTTP / 2. It seems that you should use SocketsHttpHandler instead of HttpClientHandler, but it doesn't seem to be implemented in Unity? It did not exist in netstandard (2.1.0.0) in the Visual Studio assembly browser.
So since this is a Unity problem and this package isn't targeting Unity as a supported platform (again, no nuget package targets Unity, it is luck if it works), i highly recommend going through Unity channels.
If your team is already assigned a Unity account manager, you should talk to them, and if you don't know who your TAM is, ask your team. Unity also has an internal slack that you could get on if you ask your TAM. I've always had the most success discussing roadmap issues that way instead of going straight to forums.
If you don't have a TAM (or don't have a team) then your best bet is the forums. Here is some info about .net support https://forum.unity.com/threads/unity-future-net-development-status.1092205/
You could also try their roadmap site but I haven't had a lot of success with that personally https://unity.com/roadmap/unity-platform
Thank you. I'll try to tell Unity about the problem.
Closing as answered.
Hi @m-yukio ,
Hope you are doing well. Have you ever solved the issue? Thanks a lot.
I am also interested in any updates regarding this issue.
Depenting on your platform https://github.com/Cysharp/YetAnotherHttpHandler maybe a solution for you.
I would not recommend protobuf or grpc for Unity projects. Getting it integrated is like fighting gravity - too complicated, too many steps to make it work. It is a brittle workflow. There are other options.
If you don't need the performance then you should really just keep it simple and use json
If you need the performance then you should use something with better Unity support. I would recommend MessagePack and MagicOnion. MessagePack is used in lots of very popular server technologies (like Redis) and enjoys excellent C# and Unity support. If you have C# on the server, then you can also define your message schema in C# code and share that code with your server.
If you're in a position to choose your server communication format, I would go this way.
https://github.com/MessagePack-CSharp/MessagePack-CSharp
https://github.com/Cysharp/MagicOnion
These are also created by the creator/owner of CySharp, neuecc. He specializes in creating libraries that work in both Unity and latest .NET
What version of gRPC and what language are you using?
What operating system (Linux, Windows,...) and version?
What runtime / compiler are you using (e.g. .NET Core SDK version
dotnet --info
)What did you do?
This is the gRPC Go log on the server side.
Below is the gRPC Go code that printed the error. internal/transport/http2_server.go
What did you expect to see?
What did you see instead?
It doesn't seem to support "3.4. HTTP / 2 Connection Preface". https://httpwg.org/http2-spec/draft-ietf-httpbis-http2bis.html#name-http-2-connection-preface
The gRPC core library supports the following points.
https://github.com/grpc/grpc/blob/master/src/core/ext/transport/chttp2/transport/chttp2_transport.cc#L492
The gRPC-Go supports the following points.
https://github.com/grpc/grpc-go/blob/master/internal/transport/http2_client.go#L368