MagicOnion v4 — .NET 5 and ASP .NET Core gRPC with Code-First Contracts
By: Yoshifumi Kawai
Tags: Grpc, Dotnet, Csharp

We released MagicOnion v4 from Cysharp last week.

https://github.com/Cysharp/MagicOnion/

MagicOnion has been built on the design principles of C# as Schema, Code-First Contracts for four years, immediately following the release of gRPC 1.0. Until now, we have been using gRPC C Core from Google, and now we are using the Microsoft implementation of ASP.NET Core Pure C#.

This has allowed us to share the same foundation as ASP.NET Core MVC, etc., so it’s much easier to provide gRPC and live together, such as providing HTTP/1 REST API and HTML output.

And most importantly, performance has improved.

Thanks for the ASP.NET team, we are also using it for real-time multiplay applications in games, so performance was very important.

MagicOnion can be adopted or replaced in the following use cases:

RPC services such as gRPC, used by Microservices, and WCF, commonly used by WinForms/WPF

API services such as ASP.NET Core MVC targeting Unity, Xamarin, and Windows clients

Bi-directional real-time communication such as Socket.io, SignalR, Photon and UNet

Explain the details below.

Code-First gRPC

Among the various components of gRPC, the most important one is probably the language-neutral schema and code generation by .proto.

However, MagicOnion takes a code-first design, eliminating the need for .proto by using the C# interface as a schema and sharing it. It loses language neutrality, but improves the ease of development and expressiveness.

For one thing, the lack of expressive power of the language-neutral nature of proto is solved by making it a C# itself schema, whereas proto has only a few primitives and enums, collections and maps (and no null), and MagicOnion has a C# itself By viewing it as a schema and using MessagePack for C# as the message format, (almost) all C# types are transferable.

.NET 5 recommends gRPC to replace WCF, but it suffers from the need of rewriting to .proto and the expressiveness gap. And since multiple argument-like representations of the methods of OperationContract are also possible, there is almost no gap in migration.

In MagicOnion, all types represented by DataContract can be serialized in MessagePack for C#. And since multiple argumentative representations of OperationContract methods are also possible, there are almost no migration gaps.

Bidirectional Streaming RPC vs MagicOnion StreamingHub

Although gRPC can use Bidirectional streaming RPC, it cannot implement things like getting a return value or waiting for a process to server method complete because there is only a single fire-and-foget API. Furthermore, since only one endpoint type can be used, there is no choice but to use a large amount of oneof to isolate the call.

The MagicOnion StreamingHub adds C# type contract to callee(client) and caller(server) and method routing as C# on top of Bidirectional streaming RPC. client -> server -> client calls to get return values, send errors, and wait for method completion. The implementation of this infrastructure process enables practical real-time communication with gRPC for the first time. The API is based on ASP.NET Core SignalR, so if you have experience with it, the transition should be relatively smooth.

Unity and gRPC

In MagicOnion v4, the server side is now a Pure C# implementation based entirely on ASP.NET Core Kestrel. .NET Core client side is now a Pure C# implementation based on HttpClient. However,Unity client is continue to use C Core based one. This is because .NET Core based HTTP/2 support is not yet available in Unity. In other words, MagicOnion also officially supports the use of gRPC in Unity.

MagicOnion v5 will offer its own implementation of Pure C#. Zero-allocation async/await and more with UniTask to improve performance.

gRPC’s benefit

One of the reasons why we recommend gRPC is because of the abundance of middleware on the infrastructure side by using HTTP/2. By taking advantage of these, the flexibility of building a server has increased dramatically compared to proprietary network formats.

Most software now supports HTTP/2, for example, Nginx, Envoy, and even AWS ALB has added dedicated support for gRPC.

One of the advantages of gRPC itself is the ability to consolidate the two strains of API communication and real-time communication into a single framework.

With MagicOnion, both Client and Server need only one language (C#) and one framework.

Roadmap

Creating a Unity client in v5, providing a load testing tool as a utility, and so on. The load testing tool in particular is coming soon.

Since MagicOnion itself has been in development for four years, it has already some case study. Most recently, with Unity, D4DJ Groovy Mix (Mobile Game) and Virtual Cast 2.0 (VRSNS).

I hope you will try it out, along with the new .NET 5.