{"id":15646923,"url":"https://github.com/bwplotka/unity-grpc","last_synced_at":"2025-04-30T12:34:56.908Z","repository":{"id":57570427,"uuid":"105810662","full_name":"bwplotka/unity-grpc","owner":"bwplotka","description":"gRPC lib ported to support .Net 3.5 (unity 4+) with Tutorial and example","archived":false,"fork":false,"pushed_at":"2017-10-20T07:53:00.000Z","size":17835,"stargazers_count":45,"open_issues_count":1,"forks_count":1,"subscribers_count":5,"default_branch":"master","last_synced_at":"2024-12-20T12:09:39.306Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/bwplotka.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-10-04T19:42:09.000Z","updated_at":"2024-10-27T21:56:36.000Z","dependencies_parsed_at":"2022-09-10T19:01:34.464Z","dependency_job_id":null,"html_url":"https://github.com/bwplotka/unity-grpc","commit_stats":null,"previous_names":["bplotka/unity-grpc"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bwplotka%2Funity-grpc","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bwplotka%2Funity-grpc/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bwplotka%2Funity-grpc/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bwplotka%2Funity-grpc/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/bwplotka","download_url":"https://codeload.github.com/bwplotka/unity-grpc/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":232031972,"owners_count":18462965,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-10-03T12:15:44.914Z","updated_at":"2024-12-31T21:33:07.620Z","avatar_url":"https://github.com/bwplotka.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"# unity-grpc\ngRPC lib ported to support .Net 3.5 (unity 4+) with Tutorial.\n\nIf you are interested in gRPC usage in your Unity and you don't want to wait for Unity C# .Net 4.5 support... this is a tutorial for you!\n \nAll credits for providing gRPC library goes to https://github.com/neuecc \n\n`lib/gRPC` code was copied without single change from [here](https://github.com/neuecc/MagicOnion/tree/3e04e797a00ba49807654c8c13808875c5fd92c0/src/MagicOnion.Client.Unity/Assets/Scripts/gRPC)\n\nThe idea of this short tutorial came in response to https://github.com/neuecc/MagicOnion/issues/18\n\n## Tutorial\n\nStep by step setup of example client and server to show gRPC support for Unity 4+.\n\n### Client (Unity with C# .Net 3.5)\n\n* Create new project\n* Copy `lib/gRPC` directory to your Assets (you can just drag \u0026 drop it in your unity) \n\nFrom now on, we need to solve all dependency issues to support gRPC lib and protobufs.\n\n* Install UniRx from AssetStore (async lib used by this gRPC lib)\n  * Window \u003e AssetStore\n  * Find UniRx - Reactive Extension for Unity \u003e Login \u003e Import\n  \nAt that point you should be able to build all in Visual Studio (or any IDE else you are using).\n \nLet's now run through some example of gRPC client \u003c-\u003e server communication with the client side in Unity.\nI will use standard example from grpc repo with server streaming: https://github.com/grpc/grpc/blob/master/examples/protos/hellostreamingworld.proto\n\nWe cannot use gRPC generated code for C#, because it uses .Net 4.5+ code, but we can\nstil generate protobuf messages (including serialization) that will be .Net 3.5 compatible C# data structures.\n\nThe cool part is, that you can use exactly the same proto file with service definition. Protobuf will \njust ignore this, so you can generate gRPC + protobuf messages for server (in my example it will be Golang), and\nC# protobuf messages for client. \n\nThe only manual part is to use gRPC lib's classes provided in `lib/gRPC` to call known _ServiceName_ and _Method_ you prepared. This is normally done by gRPC generated code from proto itself, but needed to recreate that manually [here](./example/csharp-client/GreeterClient.cs). We could write plugin to generate this, but having .Net 4.5 C# support in Unity \"soon-ish\", not sure if it's worth it.\n\n* Go to example directory.\n* Run `bash ./example/protogen_csharp.sh` (I am using windows migw32) to generate protobuf messages for our example.\n\nThis scripts is using protoc-3.0.0, which is provided in this repo [here](./bin/protoc-3.0.0-win32). This is standard protoc downloaded from upstream.\nYou can use `protogen_csharp` script to generate your own stuff. However, generated protobufs are already commited into this repo\nfor convenience.\n\n* Copy `example/csharp-client` to Unity Assets. (you can drag \u0026 drop it). This contains:\n  * generated proto messages\n  * manually written client\n  * Unity TestGrpcBehaviour that tries to run the service targeting `127.0.0.1:9991`\n\nThe most important part here is manually written client, so code that normally would be generated:\n\n```c#\nreturn this.invoker.AsyncServerStreamingCall\u003cExample.HelloRequest, Example.HelloReply\u003e(\n     // Your protobufs message and response as T1, T2.  \n     new Method\u003cExample.HelloRequest, Example.HelloReply\u003e(\n         // MethodType: Unary, ClientStreaming, ServerStreaming or DuplexStreaming (Bidirectional stream).\n         MethodType.ServerStreaming,\n         // This is bit manual, but basically get from your .proto service:\n         // \u003cpackage name\u003e.\u003cservice name\u003e    \n         \"example.MultiGreeter\",\n         // \u003cmethod name after \"rpc\" in your service\u003e\n         \"sayHello\",\n         // Serialization definition for request.\n         new ProtoMarshaller\u003cExample.HelloRequest\u003e(Example.HelloRequest.Parser),\n         // Serialization definition for respone.\n         new ProtoMarshaller\u003cExample.HelloReply\u003e(Example.HelloReply.Parser)\n     ),\n     this.host,\n     new CallOptions(cancellationToken: new GrpcCancellationToken(ctx)),\n     req\n );\n```\nYou need to manually implement that for each method in your proto service!\n\nFor unary calls you can switch `this.invoker.AsyncServerStreamingCall` for just `this.BlockingUnaryCall` if you don't\nwant to play with async code. (: If you wish to deal with concurrency just use `this.invoker.AsyncUnaryCall`.\n\nAfter copying the example `csharp_client` directory you should immediately see errors like:\n```\nAssets/csharp-client/Model/Greeter.cs(6,12): error CS0400: The type or namespace name `Google' could not be found in the global namespace (are you missing an assembly reference?)\n```\n\nThis is tricky part, because we need to get protobuf library that will fit with .Net 3.5\n\nI used this great fork https://github.com/emikra/protobuf3-cs.\nNuget install command from README.md totally did not work for me (visual 2013), so I ended up\nbuilding the .dll myself (using visual 2017). I provide what I built here in this repo, so:\n\n* Copy provided dll from protobuf-net35/protobuf3.dll into your unity Assets\n\nThere is a risk it will not work you (not sure even if I built for x86 or x64, so you might want to rebuild \nit from source if needed.\n\nFrom now you should be able to rebuild the Unity code. \n\nHowever when you use Unity Free version. When you run the code it will fail with (more fun!):\n```\nDllNotFoundException: grpc_csharp_ext\nGrpc.Core.Internal.NativeLogRedirector.Redirect (Grpc.Core.Internal.NativeMethods native) (at Assets/gRPC/Core/Internal/NativeLogRedirector.cs:63)\nGrpc.Core.Internal.NativeExtension..ctor () (at Assets/gRPC/Core/Internal/NativeExtension.cs:59)\nGrpc.Core.Internal.NativeExtension.Get () (at Assets/gRPC/Core/Internal/NativeExtension.cs:77)\nGrpc.Core.Internal.NativeMethods.Get () (at Assets/gRPC/Core/Internal/NativeMethods.cs:269)\nGrpc.Core.GrpcEnvironment.GrpcNativeInit () (at Assets/gRPC/Core/GrpcEnvironment.cs:314)\nGrpc.Core.GrpcEnvironment..ctor () (at Assets/gRPC/Core/GrpcEnvironment.cs:250)\nGrpc.Core.GrpcEnvironment.AddRef () (at Assets/gRPC/Core/GrpcEnvironment.cs:117)\nGrpc.Core.Channel..ctor (System.String target, Grpc.Core.ChannelCredentials credentials, IEnumerable`1 options) (at Assets/gRPC/Core/Channel.cs:87)\nGrpc.Core.Channel..ctor (System.String host, Int32 port, Grpc.Core.ChannelCredentials credentials, IEnumerable`1 options)\nGrpc.Core.Channel..ctor (System.String host, Int32 port, Grpc.Core.ChannelCredentials credentials)\nExample.Client..ctor (System.String host, Int32 port) (at Assets/csharp-client/GreeterClient.cs:52)\nTestGRPCBehaviour.Start () (at Assets/csharp-client/TestGRPCBehaviour.cs:12)\n```\n\nThis is because of some native API calls used by gRPC core. (https://github.com/grpc/grpc/issues/905)\n\nThe problem with Free Unity is that it does not support unmanaged dlls packed into per platform directories \nas we have in `lib/gRPC/Native/(...)`. (called \"plugins\" support)\n\nWhat we can do, we can copy the dll you need and place it in Unity root (above Assets!).\nYou will also need to copy this dll with you binary everywhere you want to export it on release.\nYou can find more details here: http://ericeastwood.com/blog/17/unity-and-dlls-c-managed-and-c-unmanaged\n\nOnce you provide `grpc_csharp_ext.dll` there is only last step missing.\nLast step for client-side is to pin behaviour to any game object in your scene\n\n* Create new GameObject \u003e AddComponent \u003e Put TestGRPCBehaviour.cs as Script\n\nYou can run Unity now, but it will fail... Since there is no server running around (:\n\n```\nRpcException: Status(StatusCode=Unavailable, Detail=\"Connect Failed\")\nUniRx.Stubs.\u003cThrow\u003em__6B (System.Exception ex) (at Assets/Plugins/UniRx/Scripts/Observer.cs:495)\nUniRx.Observable+\u003cToAwaitableEnumerator\u003ec__Iterator10`1[System.Boolean].MoveNext () (at Assets/Plugins/UniRx/Scripts/UnityEngineBridge/Observable.Unity.cs:939)\n```\n\nThe client is done, but now all we need to do is to spin up our server to handle gRPC traffic!\n\n### Server (Go)\n\nPrepate go enviroment (golang installed, GOPATH exported)\n\n* Follow https://grpc.io/docs/quickstart/go.html\n* `go get github.com/google/protobuf/...`\n* Run `bash ./example/protogen_go.sh`\n* Start server using `go run example/go-server/server.go`\n\nIi will listen on `127.0.0.1:9991`\n\n* Now let's start our unity again.\n\nYou should be able to see logs on both Go server and Unity with gRPC communication!\n\nI hope this tutorial will help to create your own gRPC client (: \n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbwplotka%2Funity-grpc","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbwplotka%2Funity-grpc","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbwplotka%2Funity-grpc/lists"}