GrpcWebSocketBridge icon indicating copy to clipboard operation
GrpcWebSocketBridge copied to clipboard

Error when serving WebGL build externally rather than through server code

Open Cherden opened this issue 1 year ago • 5 comments

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:

  • Unity Version: 2022.3.18
  • GrpcWebSocketBridge Version: 1.3.0
  • Browser: Chrome Version 127.0.6533.120
  • Starting server with dotnet version: 8.0.400

Cherden avatar Aug 21 '24 11:08 Cherden

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 avatar Aug 21 '24 12:08 Cherden

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:

  • setting new GrpcWebSocketBridgeHandler(true)
  • removing usages of .AsUniTask() extension functions

Cherden avatar Aug 21 '24 13:08 Cherden

I just had exactly the same problem with this, just that in my case this happened when trying to test the connection to the server from the Unity Editor. It seems that the Unary connection in these scenarios only works if forced via WebSocket.

ShikiGami avatar Nov 11 '24 03:11 ShikiGami

This problem is making my code unusable, because if I force WebSocket for Unary, then if I try to call an [Authorize] service, it will fail, but if I don't force WebSocket, then it fails with the Content-Type 'application/octet-stream' is not supported error, and even if I force the Content-Type to application/grpc then I get RpcException: Status(StatusCode="Internal", Detail="Request protocol 'HTTP/1.1' is not supported.")

ShikiGami avatar Feb 01 '25 20:02 ShikiGami

I think I figured out why this is happening, and the culprit seems to be: https://github.com/Cysharp/GrpcWebSocketBridge/blob/8e37d22c8110816b2d96bf6c7aa7eae306705a6d/src/GrpcWebSocketBridge.Client.Unity/Assets/Plugins/GrpcWebSocketBridge/GrpcWebSocketBridge.Client/Unity/UnityWebRequestHttpHandler.cs#L20

Here, requestMessage.Headers.Accept is empty, which means that it doesn't receive the necessary application/grpc-web Content-Type that is set at requestMessage.Content.Headers.ContentType.

In my code, by changing requestMessage.Headers.Accept to requestMessage.Content.Headers.ContentType, everything worked correctly.

ShikiGami avatar Feb 01 '25 22:02 ShikiGami

This issue is stale because it has been open 180 days with no activity. Remove stale label or comment or this will be closed in 30 days.

github-actions[bot] avatar Aug 01 '25 00:08 github-actions[bot]