如何在Unity Game客户端(C#/。Net)和基于滋补的服务器之间使用GRPC

发布于 2025-02-14 00:26:29 字数 3131 浏览 0 评论 0 原文

因此,我使用 tonic板条板条使用。我写了所有的原始文件,我可以使用基于补品的客户端和 grpcurl 服务器端的问题。

我有一个基于Unity 3D的游戏,我想用作客户。 Unity使用C#/。网/单声道,因此从理论上讲,让GRPC客户端起作用应该很容易。事实证明,这并不容易。

根据Internet(特别是 https://grpc.io/blog/blog/grpc-csharp-future /)我们应该使用 grpc.net.client 软件包。因此,我使用非常有用的 nugetforunity 工具将其删除了。

我得到以下错误,至少非常有用

PlatformNotsupportedException:GRPC需要在不支持HTTP/2上支持GRPC的.NET实现上进行额外的配置。必须使用grpcchanneloptions.httphandler指定HTTP提供商。配置的HTTP提供商必须支持HTTP/2或配置以使用GRPC-WEB。请参阅 https://aka.ms/aspnet/prpc/netstandstandard 有关详细信息。

经过一番谷歌搜索后,我遇到了以下链接,这清楚地表明Unity/Xamarin和其他人不支持Grpc.net.Client。

https://github.com/grpc/grpc/grpc/grpc/grpc-dotnet/issues/1309 #issuecomment-850303082

https:// https://learn.microsoft.com/en-en-us /aspnet/core/grpc/netstandard?view=aspnetcore-6.0

总之:

.NET实现不支持HTTP/2(例如UWP,Xamarin和Unity)可以使用GRPC-WEB作为替代方案。

这听起来很直截了当,所以我导入了grpc.net.client.web,并按照文章的建议将其连接起来。

至少这次请求通过了,但是GRPC服务器开始引起“连接重置对等”错误。

突破了TCPDUMP,我意识到GRPC Web提出了Tonic不喜欢的HTTP 1.x请求。

我发现在补品中具有以下描述,并将其设置为“ true”。

接受HTTP1请求仅在开发启用GRPC-WEB的服务时才有用。如果此设置设置为true,但未正确配置服务以处理GRPC-WEB请求,则您的服务器可能会返回混淆(但正确)协议错误。

执行此操作后,服务器至少会接受连接,但是我开始遇到一个错误:

(statuscode =“取消”,详细信息=“响应中找到的grpc-status。”)

我看到了这个问题 https://github.com/grpc/grpc/grpc-dotnet/issues/1164 ,但对此无济于事 全部。

似乎补品不喜欢grpc.net.client.web实现GRPC-WEB,或者只是不适当地支持它。

然后,我花了很长时间试图通过使用TLS强迫GRPC-WEB使用HTTP/2(我确定这是不合适的),但是我无法让TLS握手与Tonic服务器一起使用。我一直收到模糊的消息:

tlsexception:握手失败 - 错误代码:unitytls_internal_error,验证结果:(一些大数字)

我很确定是因为Tonic期望TLS 1.3和Mono的版本,Unity使用的最大TLS版本具有1.2的最大tls版本(即使那样)仅受到最近的支持)。我无法弄清楚如何配置补品/Rustls接受较低版本的TLS。

在更详细地阅读文档后,我还意识到,如果我使用GRPC-WEB,我将失去许多良好的GRPC功能,例如流媒体,因此我决定避免使用这种方法。

有人知道一种将自定义HTTP客户端插入GRPC库中的方法吗?如果没有,有人知道解决方法至少可以让我让RPC正确工作吗?

谢谢!

So I have a gRPC server written in Rust using the Tonic crate. I have all the proto files written and I can make requests using a Tonic based client and grpcurl so there are no issues on the server side.

I have a Unity 3D based game which I want to use as a client. Unity uses C#/.NET/Mono so in theory it should be easy to get a gRPC client working. It turns out it isn't so easy.

According to the internet (in particular https://grpc.io/blog/grpc-csharp-future/) we should be using the Grpc.Net.Client package. So I dropped that in to Unity using the very useful NuGetForUnity tool.

I got the following error which at least was very informative

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.

After some Googling I came across the following links which make it clear that Unity/Xamarin and others don't support Grpc.Net.Client.

https://github.com/grpc/grpc-dotnet/issues/1309#issuecomment-850303082

https://learn.microsoft.com/en-us/aspnet/core/grpc/netstandard?view=aspnetcore-6.0

In summary:

.NET implementations that don't support HTTP/2, such as UWP, Xamarin, and Unity, can use gRPC-Web as an alternative.

That sounded straight forward so I imported Grpc.Net.Client.Web and hooked it up as suggested in the article.

At least the request went through this time, but the gRPC server started causing a “Connection reset by peer” error.

Breaking out tcpdump, I realised that gRPC web makes HTTP 1.x requests which Tonic does not like.

I found the 'accept_http1' config option in Tonic which has the following description and set to to "true".

Accepting http1 requests is only useful when developing grpc-web enabled services. If this setting is set to true but services are not correctly configured to handle grpc-web requests, your server may return confusing (but correct) protocol errors.

After doing that, the server would at least accept the connection, but I started getting an error:

(StatusCode="Cancelled", Detail="No grpc-status found on response.")

I saw this issue https://github.com/grpc/grpc-dotnet/issues/1164 but it didn't help at all.

Seems like Tonic doesn't like the Grpc.Net.Client.Web implementation of gRPC-web or just doesn't support it properly.

I then spent ages trying to force gRPC-Web to use HTTP/2 by using TLS (which I’m not sure even made sense) but I couldn’t get the TLS handshake to work with the Tonic server. I kept getting the vague message:

TlsException: Handshake failed - error code: UNITYTLS_INTERNAL_ERROR, verify result: (some large number)

I’m pretty sure it is because Tonic was expecting TLS 1.3 and the version of Mono that Unity uses has a maximum TLS version of 1.2 (and even that was only supported recently). I couldn’t work out how to configure Tonic/Rustls to accept a lower version of TLS.

I also realised after reading the documentation more thoroughly that I would lose a lot of good gRPC features such as streaming if I used gRPC-web so I decided to avoid that method.

Does anyone know of a way to plug in a custom HTTP client into the gRPC library that does all the stuff that Unity doesn't (e.g. HTTP/2 and TLS 1.3)? If not does anyone know of a workaround that will let me at least get the RPC working correctly?

Thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

吃兔兔 2025-02-21 00:26:29

我不确定这是否是理想的答案,但至少在我的情况下有效。我最终使用了grpc.core而不是推荐的grpc.net.client,以使其全部工作,

grpc.core被弃用它仍然有效,维护期限已延长到直到2023年5月。

它的功能完整,因此主要问题是在维护期用完时没有获得安全更新,但是希望那时Unity将具有HTTP/2实现!

我怀疑它起作用是因为它是本机库上具有其自己内置的HTTP实现的包装器,这意味着我们可以绕过Unity的旧实现。这种评论证实了这种怀疑:

许多接口阵容,因此我从代码角度进行的唯一一件事是删除grpc.net.client。从项目中删除,添加 grpc.core ,然后替换

var channel = Grpc.Net.Client.GrpcChannel.ForAddress("http://127.0.0.1:50051");

 var channel = new Grpc.Core.Channel("127.0.0.1:50051", ChannelCredentials.Insecure);

但是,有一个很大的警告。本机库是作为grpc.core nuget软件包的一部分提供的,并且不安装在正确的位置。您可以通过下载 nuget file 手动,将nuget文件提取为zip文件,然后检查 runtimes 文件夹。

目前,仅针对以下平台有预编译的二进制文件:

grpc.core

  • linux-arm64
  • linux-x64
  • osx-x64
  • win-x64
  • win-x86

grpc.core.m1

grpc.core.xamarin

  • fig
  • ios ios android

for Platform for Platform(S)您想要并将其复制到“资产/插件”中Unity项目中的目录。您可能需要以团结选择它们,并确保正确设置所有架构和平台。

您还需要确保文件的基本名称为“ grpc_csharp_ext”。例如,

dllnotfoundException:grpc_csharp_ext汇编:类型:成员:(null)

此方法无法在其他平台上使用。如果您愿意投入工作,您也许可以为其他平台编译自己的版本!

来源位于 htttps://github.com/grpc/grpc/grpc/grpc/tree/master /src/csharp

我希望这对某人有帮助,我花了很长时间才能追踪!

I'm not sure if this is the ideal answer, but it at least works in my situation. I ended up using Grpc.Core instead of the recommended Grpc.Net.Client to get it all working

While Grpc.Core is deprecated it still works, and the maintenance period has been extended to until May 2023.

It is feature complete, so the the main issue is not getting security updates when the maintenance period runs out, but hopefully by then Unity will have a HTTP/2 implementation!

I suspect it works because it is a wrapper over a native library that has its own HTTP implementation built into it, which means we get to bypass Unity's old implementation. This suspicion is confirmed by this comment: Why does Xamarin Android fails to send GRPC/Http2 requests?

A lot of the interfaces line up, so the only thing I had to do from a code perspective was remove Grpc.Net.Client from the project, add Grpc.Core and then replace

var channel = Grpc.Net.Client.GrpcChannel.ForAddress("http://127.0.0.1:50051");

with

 var channel = new Grpc.Core.Channel("127.0.0.1:50051", ChannelCredentials.Insecure);

However, there is a big caveat. The native libraries are provided as part of the Grpc.Core Nuget package and are not installed in the right place automatically. You can see them by downloading the nuget file manually, extracting the nuget file as a zip file and checking the runtimes folder.

Currently there is only pre-compiled binaries for the following platforms:

Grpc.Core

  • linux-arm64
  • linux-x64
  • osx-x64
  • win-x64
  • win-x86

Grpc.Core.M1

Grpc.Core.Xamarin

  • iOS
  • Android

Find the binary library for the platform(s) you want and copy it into the "Assets/Plugins" directory in your Unity project. You might need to select them in Unity and make sure all the architectures and platforms are set correctly.

You also need to ensure that the file's base name is "grpc_csharp_ext". For example, the binary in the Grpc.Core.M1 project is named "grpc_csharp_ext.arm64.dylib", and needs to be renamed to "grpc_csharp_ext.dylib" or you'll get the error:

DllNotFoundException: grpc_csharp_ext assembly: type: member:(null)

This method won't work out of the box for the other platforms. You might be able to compile your own version for other platforms if you are willing to put in the work though!

The source is at https://github.com/grpc/grpc/tree/master/src/csharp

I hope this helps someone, it took me a really long time to track down!

独木成林 2025-02-21 00:26:29

尽管非常有帮助,但我无法完全使用Seans解决方案来工作。本机库导致Unity在试图打开服务器的通道失败后,在退出 /重新编译上冻结。

但是,cysharp以 arthotherhtttpphandler 。这使用了用Rust编写的自定义本机库为Unity带来HTTP/2支持。这样,您可以使用grpc-dotnet而不是传统grpc.core。

Although very helpful, I couldn't fully get this to work using Seans solution. The native library caused Unity to freeze on quit / recompile after unsuccessfully trying to open a channel to the server.

However, Cysharp comes to the rescue with YetAnotherHttpHandler. This uses a custom native library written in Rust to bring HTTP/2 support to Unity. This way you can use grpc-dotnet instead of the legacy GRPC.Core.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文