Cysharp / GrpcWebSocketBridge

Yet Another gRPC over HTTP/1 using WebSocket implementation, primarily targets .NET platform.
MIT License
76 stars 12 forks source link

Error when serving WebGL build externally rather than through server code #39

Open Cherden opened 3 weeks ago

Cherden commented 3 weeks ago

Hi! Thanks for implementing the bridge, it looks like it will really help us. We're currently facing a problem integrating it in our solution though. We cannot server our client in wwwroot like in the sample project but do it externally.

When trying to access a grpc service from a client served outside of wwwroot the server returns the error Request content-type of 'application/octet-stream' is not supported.. To reproduce our problem with a minimal setup, you would just need to "Build and run" the sample Unity project to see the error we're facing.

As a sanity check I have built the sample Unity client myself and put the build in the wwwroot folder, which works.

Could you please help us with how we can configure the server for that scenario? Thanks in advance!

Some information:

Cherden commented 3 weeks ago

I narrowed the issue down. The error goes away when I set forceWebSocketMode to true in the GrpcWebSocketBridgeHandler constructor. The problem now boils down to this snippet:

#if UNITY_WEBGL && !UNITY_EDITOR
    internal sealed class SynchronizationContextInitializer
    {
        [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)]
        private static void InitializeSynchronizationContext()
        {
            System.Threading.SynchronizationContext.SetSynchronizationContext(null);
        }
    }
#endif

If that is configured, UniTasks in our application do not terminate anymore and block forever. I tried to configure it the following way but that didn't solve it.

#if UNITY_WEBGL && !UNITY_EDITOR
    internal sealed class SynchronizationContextInitializer
    {
        [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)]
        private static void InitializeSynchronizationContext()
        {
            System.Threading.SynchronizationContext.SetSynchronizationContext(new UniTaskSynchronizationContext());
        }
    }
#endif

Do you have an idea how we can configure it so we can use UniTasks but also the grpc bridge?

PS: I verified that removing the initial setup of my client using UniTasks lets me connect to the grpc service. So we can currently only have tasks or grpc integration which looks like a bug. To give more context of the project setup: It is utilizing a library using System.Threading.Tasks. Internally in our Unity project we are using UniTask and calling the extension method .AsUniTask() before awaiting them. The first task we await that way does not terminate and block forever.

Cherden commented 3 weeks ago

It works now! Removing .AsUniTask() from the tasks from the library made them terminate. Could that be a bug with that extension function in that specific setup then? I'll leave this issue open for you to see but the original problem is solved. Feel free to close.

To summarize, we solved it by: