#WebGL + SimpleWebTransport + React

108 messages · Page 1 of 1 (latest)

dry lake
#

Hello everyone, I am encountering problems with asio transport and mirror, I have a project in react with a layout that has a canvas where my unity webgl build is mounted, but I want to unload this build and mount another component with a different build, When I disconnect from Asio Transport and re-enter the same build or another, when I try to connect it stays in a loading loop, it is possible that Asio Transport has to disconnect or release in some specific way before unmounting my first Webgl build.
I am using react-unity-webgl library to mount the canvas and unity 2022.35f1
Docs library: https://react-unity-webgl.dev/

Bringing your Unity Games to the Web since 2017!

wicked remnant
#

Netcode with UnityTransport works perfecly with canvas and react. Htere is no problem with listeners or second charges...

paper crag
# dry lake Hello everyone, I am encountering problems with asio transport and mirror, I hav...

Hi!
(thanks @wicked remnant for pointing this out, do ping me for #asio-server-transport related questions please)
#asio-server-transport uses the built-in transports on the client, so unless I'm mishandling the client shim it shouldn't be any different from the regular websocket transport
Can you try making a client build with the regular simplewebtransport (if you set the same port/settings it is compatible - thats all I do anyways) and see if that has the same issue?

#

section where I set the SWT settings as a guide

dry lake
#

the same error with simplewebtransport configured

#

maybe is problem #websockets simple web transport

#

WebGL + SimpleWebTransport + React

paper crag
dry lake
#

It's probably some thread, eventlistener or process that remains undismantled when Unity closes

#

it's hard to find

paper crag
wicked remnant
#

Its not a dev build, we will try.

dry lake
paper crag
#

from the looks of it: WebSocketClientWebGl_Connect -> WebSocketClientWebGl_ErrorCallback

#

so thats just related to the websocket connection failing?

wicked remnant
#

It looks like

paper crag
#

if you check the network tab of the dev tools you should be able to see more details about the websocket connection attempt

dry lake
#

I think so

wicked remnant
#

But only if is the second time you charge other or same project in the same canvas, look like there are an open ws connection or something

paper crag
#

(ivan shared the url to me privately)
it seems like the bridge code between JS<>C# is a bit confused by the loading/unloading/reloading or whatever happens

#

do you guys have any detail on what the unload button does?

#

I'm guessing it doesn't clear the global memory properly somehow and still has references to the unloaded unity callbacks for the SWT stuff

#

@latent wind (sorry for pulling you in here 😅) might have an idea how the jslib stuff works?

latent wind
#

is there a tldr of the issue?

paper crag
#

my guess was the global state is somehow messed up and it's trying to call into the destroyed unity instance

#

just a guess though and I might be wrong

latent wind
#

the way I understand jslib stuff, is that unity loads it internally (as in, not in global JS scope). so loading a 2nd instance of unity in the webpage should make a different instance, so have its own copy of state and functions.

#

but I've not actually tested it

dry lake
#

the react-unity-webgl library and the method unload clean the cache and prepare all before disconnect unity

paper crag
#

not sure then 😦

#

thanks for taking a look as well

dry lake
latent wind
#

the SimpleWeb.jslib works like this:

  • connect create new websocket, stores it in webSockets: [], using next: 1,, and return index to unity
  • the other methods then use index to get the websocket instance and use it

so if you open 2 websocket connections at once, they should have different index.

#

if you create a new unity instance, by doing something like this, (which I assume is waht the react thing does?) then it should make a new "static" object with next: 1 again

dry lake
#

ok, I understand this, I'm going to try to have the second room generated in a different order

latent wind
#

what you could do to test this, is log what is in the SimpleWeb object inside the connect function

dry lake
#

is posible create the key for one instance?

dry lake
#

i'm working in the new project for testing this

wicked remnant
#

But i dont know about ws array index.

#

this log: ", is log what is in the SimpleWeb object inside the connect function" ok, on it.

dry lake
#

const unload: () => Promise<void>
Requests the UnityInstance to be unloaded from memory in order to be unmounted from the DOM.

dry lake
#

building

latent wind
#

is this a bug 👀 should this be using const/var

dry lake
#

Can this be the problem if you try to overwrite on the same variable?

#

done, you have link to testing in pm

latent wind
#

Just tested it in one of my projects, new unity instance does reset the next variable

latent wind
#

but the const SimpleWeb = { object is a different object. so has different next counter and array, so are different, so multiple game instance shouldn't conflict

latent wind
# dry lake

these could be from the old websocket instance. since the game instance is unloaded it will error?

#

so maybe its not being closed when unity is destroyed

latent wind
# dry lake

just checking, it is this line it is coming from

#

so it is new message being sent to the websocket, which is then calling unity. and then unity is breaking, I assume because is is the old instance but I'm not sure

paper crag
#

so my guess was right? ugh

dry lake
#

Thank you very much, I will continue tomorrow.

dry lake
#

My question is, if the problem is due to poor management of the code of our application or is it a problem with the Unity build to force the use of NetCode?

latent wind
paper crag
#

one easy workaround I can think of would be embedding the unity thing in an iframe you just reload

#

not sure if that's going to work for your use case though, not done much with webgl unity

dry lake
#

It doesn't work, I have created a function on my website that sends a message to Unity and from Unity I disconnect the client, but when it enters a second time the same problem appears.

#
    {
        UnloadTransport();
    }

    public void UnloadTransport() {
        transport.ClientDisconnect();
        Debug.Log(">>Disconect Connection Client");

    }```
#

I find it very strange that it works well with thelepathy and does not work with simplewebtransport, webgl trash

paper crag
#

unless I got it wrong and I'm the confused one

#

since it happened too when the websocket couldn't connect

latent wind
#

will probably need to add logs to the .jslib to find out for sure

#

we can take advantage of global scope to find out for sure which socket is giving the error

wicked remnant
#

What jslib??? There is not jslibs in our project. Just NetworkManager and SimpleWebTransport

latent wind
wicked remnant
#

Who has developed the SimpleWeb Transport? Can we ask someone for help?

latent wind
#

that would be me lol

wicked remnant
#

jeje, I have been all day trying posible logs & fixes, but nothing...

wicked remnant
# latent wind that would be me lol

Error don't comes from onMessage event. First error comes from onOpen event:
Runtime.dynCall('vi', openCallbackPtr, [index]);
In the seccond conection when try to connect...

wicked remnant
#
    // fix for unity 2021 because unity bug in .jslib
    if (typeof Runtime === "undefined") {
        // if unity doesn't create Runtime, then make it here
        // dont ask why this works, just be happy that it does
        Runtime = {
            dynCall: dynCall
        }
    }

    const address = UTF8ToString(addressPtr);
    console.log("Connecting to " + address);
    // Create webSocket connection.
    webSocket = new WebSocket(address);
    webSocket.binaryType = 'arraybuffer';
    const index = SimpleWeb.AddNextSocket(webSocket);

    // Connection opened
    function onOpen (event) {
        console.log("Connecting to " + address);
        Runtime.dynCall('vi', openCallbackPtr, [index]);
    }
    
function onMessage(event) {
    if (event.data instanceof ArrayBuffer) {
        var array = new Uint8Array(event.data);
        var arrayLength = array.length;
        var bufferPtr = _malloc(arrayLength);
        var dataBuffer = new Uint8Array(HEAPU8.buffer, bufferPtr, arrayLength);
        dataBuffer.set(array);
        Runtime.dynCall('viii', messageCallbackPtr, [index, bufferPtr, arrayLength]);
        _free(bufferPtr);
    }
    else {
        console.error("message type not supported")
    }
}

function onError (event) {
    console.error('Socket Error', event);

    Runtime.dynCall('vi', errorCallbackPtr, [index]);
}


webSocket.addEventListener('close', function (event) {
    console.log("Disconnected from " + address);
    Runtime.dynCall('vi', closeCallBackPtr, [index]);
    //Unsubscrive all other events
    webSocket.removeEventListener('message', onMessage);
    webSocket.removeEventListener('open', onOpen);
    webSocket.removeEventListener('error', onError);    
});


webSocket.addEventListener('message', onMessage);
webSocket.addEventListener('open', onOpen);
webSocket.addEventListener('error', onError);

    return index;
}
#

😁

latent wind
#

everything I've read says you dont need to remove the listeners on close 🤔

#

btw, add a var in front of webSocket, so it isn't in global scope

#

I'm not sure if that is causing any issues

#

but it is possible some other js library is checking for and using the global webSocket variable and breaking stuff

wicked remnant
#

Nop, sorry

#

I forget to remove it

#

It was an error, was trying with iframes...

#

with iframes it works well, but we need canvas. And problem comes with canvases.

latent wind
#

Just to debug things, you could try this. I've added some logs so we can confirm which websocket instance is giving the errors

latent wind
#

I worked out what is going wrong from the logs @wicked remnant sent me

the problem is this part

    // fix for unity 2021 because unity bug in .jslib
    if (typeof Runtime === "undefined") {
        // if unity doesn't create Runtime, then make it here
        // dont ask why this works, just be happy that it does
        Runtime = {
            dynCall: dynCall
        }
    }

because it is define Runtime on the global scope, and not on the current unity instance.

#

so I think we need a different jslib file for unity 2021+ vs older versions 🤔

latent wind
#

Great, now I just need to work out which versions of unity use dynCall vs Runtime.dynCall lol

wicked remnant
#

uff, im working wit LTS (2022.3.5f1)

dry lake
#

Wow James, tu realmente you are the boss! 🐐

loud violet
#

@dry lake @wicked remnant Mirror has been updated to put websocket and Runtime both in local scope, tested with Unity 2019 - 2022 LTS releases.

dry lake
#

Thank you very much @loud violet

wicked remnant
wicked remnant