NavidK0 / SimpleGraphQL-For-Unity

A simple graphQL client that allows one to use .graphql files (or code) for queries, mutations, and subscriptions with Unity.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Can WebGL be fully supported?

johanhelsing opened this issue · comments

Hi, this is a really cool project! I was considering doing something similar myself/forking the "graphQL-client-unity" project because I didn't like how it hides too much behind its gui in scriptable objects, and I also wanted something that was a Unity package. This project seems like a really good start.

Now, I mainly develop for WebGL, though. So it would be good to clarify exactly what works, and what doesn't.

This should work with all platforms (Mono/IL2CPP) except for WebGL, since Unity WebGL has issues with threading. If you are using WebGL, this package may be hit-or-miss for you at the present time. It makes use of UnityWebRequest where possible, but the WebSockets are the main issue, so subscriptions may not properly work. If you do not need subscriptions, WebGL may work just fine.

Specifically, the "may or may not" without WebSockets part may be good to clarify.

I think some parts of the Task API may be problematic on WebGL, but I don't know enough about it to say whether the parts used here are safe for WebGL or not, but in any case most of it should be possible to fix by using UniTask instead, in any case that's what I normally use myself to be on the safe side.

It would also be cool to check if the solution proposed here is enough to be able to support subscriptions on WebGL as well.

I'll do some prototyping, just wanted to say hi and hear your thoughts on:

  • Adding CySharp.UniTask as a dependency if there are issues with Task on WebGL
  • Alternatively adding CySharp.UniTask as an optional dependency and have ifdefs to alias to it installed.
  • Add some jslib helper code to support subscriptions

Hi Johan!

I made this for the same reasons as you say, I felt that writing GraphQL queries within the Unity GUI was cumbersome and slow. I much preferred writing GraphQL files and testing them within GraphiQL.

The reason that I originally wrote that WebGL "may or may not" work properly is precisely because of the problem with websockets on WebGL. The websockets are just used for subscriptions though, so if you don't need those, then it works just fine. (But most people probably use GraphQL for the subscription part.)

Now, we at Last Abyss don't use WebGL with real-time networking capabilities for anything at the moment, so it's hard to say if I would be able to test a proper WebGL project with GraphQL integration. I would definitely need help with that. I also would like to add some proper tests into the package at some point, but dev bandwidth is low for us right now.

We currently don't even use GraphQL for any of our active projects at the moment, so testing this package is already fairly difficult. If you would like to try out this package (and figure out issues with WebGL), you are more than welcome to! We can figure out solutions for WebGL as we get to them.

As for my thoughts:

https://gamedev.stackexchange.com/questions/176842/how-can-i-use-websockets-in-a-unity-webgl-project
The solution proposed here is definitely interesting. If it's unobtrusive to the other platforms, we could definitely add this in with no issues.

  • Adding CySharp.UniTask as a dependency if there are issues with Task on WebGL
    I wouldn't do this directly, see below.

  • Alternatively adding CySharp.UniTask as an optional dependency and have ifdefs to alias to it installed.
    This is something that could be added. Perhaps some kind of #ifdef with an installer if WebGL is detected, and then an #else for uninstalling the dependency when the platform is switched again.

  • Add some jslib helper code to support subscriptions
    This can definitely be supported with the solution proposed above. I am not entirely familiar with calling native browser functionality from Unity WebGLs, so perhaps you could give some insight on how this works?

@johanhelsing Would you like write access to the repo? Your contributions have already been very valuable to the project.

Hi Navid!

The reason that I originally wrote that WebGL "may or may not" work properly is precisely because of the problem with websockets on WebGL. The websockets are just used for subscriptions though, so if you don't need those, then it works just fine. (But most people probably use GraphQL for the subscription part.)

Ok, I think I get it :) Just hoping we can change "If you do not need subscriptions, WebGL may work just fine." to "If you do not use subscriptions, WebGL will work just fine.".

we at Last Abyss don't use WebGL with real-time networking capabilities for anything at the moment, so it's hard to say if I would be able to test a proper WebGL project with GraphQL integration.

I'm using mutations and queries using this library in a small game I'm working on. So far no issues with WebGL. I can update the readme if nothing bad happens the next few days.

Alternatively adding CySharp.UniTask as an optional dependency and have ifdefs to alias to it installed.

This is something that could be added. Perhaps some kind of #ifdef with an installer if WebGL is detected, and then an #else for uninstalling the dependency when the platform is switched again.

Great, then we have a backup plan of sorts :) Hopefully we don't need it 🤞. I think as long as we don't use anything that starts new threads (like Task.Delay for instance) we should be good, though I'm no expert on this.

Add some jslib helper code to support subscriptions

This can definitely be supported with the solution proposed above. I am not entirely familiar with calling native browser functionality from Unity WebGLs, so perhaps you could give some insight on how this works?

Nice :)

I did it like this in another project

#if UNITY_WEBGL
#if !UNITY_EDITOR
using System.Runtime.InteropServices;
#endif
using UnityEngine;

public class WebGLHelpers : MonoBehaviour
{
#if UNITY_EDITOR
    public static int AddOpenUrlInNewTabClickHandler(string url)
    {
        Debug.LogWarning("JavaScript doesn't work in the editor. Make a build or switch platforms.");
        return 0;
    }
#else
    [DllImport("__Internal")]
    public static extern int AddOpenUrlInNewTabClickHandler(string url);
#endif
}
#endif // UNITY_WEBGL

Then the actual js is in a .jslib file which is following a special unity convention and has access to the browser apis.

As for subscriptions, I'm not completely sure if I have the need for it yet, I'll have a go at it if/when I need it.

@johanhelsing Would you like write access to the repo? Your contributions have already been very valuable to the project.

Thanks! That would be really cool 😄

I have some questions regarding how you like to run things, but I'll open a separate issue for this to not spam this thread in case anyone else wants to have a go at the rest of the WebGL stuff later :)

@NavidK0 This project looks like it should solve it: https://github.com/endel/NativeWebSocket

Would you be ok with adding a dependency?

@NavidK0 This project looks like it should solve it: https://github.com/endel/NativeWebSocket

Would you be ok with adding a dependency?

This project looks good, no DLLs required. Yeah, we can add this for WebGL support. I would only use it for WebGL support and not rewrite the core system so that platforms like game consoles aren't affected.

@johanhelsing On second thought, it might actually be worth rewriting the socket code entirely using NativeWebSocket instead? It seems it uses System.Net.Websockets anyways, so it should work just fine on consoles... (I think...)

Then we'd be able to keep the codebase clean while also getting WebGL/HTML5 support for "free".

commented

hey did you start doing this? I think this is the way to go, too.

hey did you start doing this? I think this is the way to go, too.

Me? No, haven't had a need graphql for a while, so feel free to take the lead if you want to!

I have not added new features to this library either, as we haven't required GraphQL in our games for a long while. Overall, I'd say it's in a stable state though.

Unfortunately, changing the internal web socket to use NativeWebSocket requires much testing that I don't have the time for. As Johan says though, feel free to add it in if you want it!