#Discord Activites + Netcode for GameObjects

1 messages · Page 1 of 1 (latest)

winged elbow
#

Hi, I'm trying to use Netcode for GameObjects with Discord's Embedded SDK which uses a proxy and embeds a WebGL application in an iframe.

@drowsy depot Sorry for the ping but I found a few messages from you in the Discord developer server concerning this and was just wondering if you had any success with a solution to get the Unity transport to work with Discord's activities, and if you have any configurations that may help
I am also using Dissonity V2 however I don't know if that's relevant

So far, I've

  • Checked Use WebSockets and Use Encryption on the Unity transport
  • Am using the address of my discord client's proxy ((clientid).discordsays.com) as the WS address
  • Used the port 7000 in the transport

Then, I have a MonoBehaviour to start the client and server

  • If it is the server build, I read the certificate and private key for mydomain.com and call
transport.SetServerSecrets(certPem, keyPem);
  • If it is the client build, I call
transport.SetClientSecrets($"{clientid}.discordsays.com");

The server runs properly, however the WebSocket connection from the client is blocked because Unity attempts to access port 0. I'm not familiar with networking so I don't know what exactly this means and if I've done something wrong

Unity.framework.js:15485 Refused to connect to 'wss://(clientid).discordsays.com:0/' because it violates the following Content Security Policy directive: "connect-src https://(clientid).discordsays.com/ wss://(clientid).discordsays.com/

In the URL mappings on the Discord portal, I only have 1 root mapping for mydomain.com. Not sure what I should change to allow Unity's websockets to work since I don't really know much about networking

Again sorry for the ping, but was just wondering if you had a working configuration already since it'd save the effort of a lot of trial and error rebuilds. Thanks 🙏

winged elbow
#

Quick update, I no longer have the CSP violation by instead doing

transport.SetClientSecrets($"{clientid}.discordsays.com/socket");

and adding a mapping for /socket to api.mydomain.com:7777/
However now I just have it that it fails to connect to server, presumably because my routing is wrong
I'm using cloudflared but I don't really know what ports Unity uses and what to create tunnels for

drowsy depot
#

The issue with the proxy was trying to use the Relay Service. I haven't looked at it since GDC.

winged elbow
#

Ah right I see, nws

#

I guess I'll keep trying to get it to work with Unity transport

drowsy depot
#

Connecting to a dedicated server shouldn't have any issues

winged elbow
#

but Unity is attempting to connect to

#

I'm a bit confused on what part is wrong here

#

If the port is ommitted should I be forwarding some other port?

#

If I omit the port in cloudflared then attempting to connec to the socket returns error code 200

#

Oh wait that's success

#

But socket:0 doesn't work, idk why unity is adding the :0

#

Discord doesn't let me add the colon in the forwarding rules either

#

Bit odd, let me do some more reading on Cloudflare's end to see if I did something wrong there

drowsy depot
#

Also if you are using NGO, you shouldn't have to mess with the transport directly.

winged elbow
#

How do I poiint the client at discord's proxy then?

#

Since any other URL like my direct IP with port forwarding or the domain I have will be blocked by Discord

drowsy depot
#

I'll check back in on it this evening when I get off work. But if I remember correctly, the client should point to the server domain. The proxy is to allow the server to communicate back to the client.

winged elbow
#

Reply whenever is convenient 🙏 ur a lifesaver

#

I'll try to find some other resources and check the discord developer server for more info on the proxy, I'll let u know if I make any progress

#

My tunnel now works with wss://clientid.discordsays.com/socket, but unity is requesting wss://clientid.discordsays.com/socket:0

#

Not sure if it's cause I messed up something with the transport

#

I'm unable to add a mapping on discord containing : so idk

winged elbow
#

Discord's patchUrlMapping also doesn't seem to work since the requests don't happen from JS but from WASM which doesn't seem to have been patched

#

Unfortunate

#

So I think I do have to directly use the proxy URL: But I'm not sure why it adds the port at the end and it refuses to connect. Really odd

#

Gonna take a break on it for a bit probably

winged elbow
#

Unfortunately still no luck, but I feel the main issue is with transport.SetClientSecrets(string)

#

If I set it to my domain name, it'll violate discord's CSP by trying to make a call to that domain

#

If I set it to the discord proxy url, I again get

Unity.framework.js:15485 Refused to connect to 'wss://(clientid).discordsays.com:0/' because it violates the following Content Security Policy directive: "connect-src https://(clientid).discordsays.com/ wss://(clientid).discordsays.com/
#

So yeah, I'm missing something wtih the SetClientSecrets. If I don't use encryption, the CSP will block it for doing a ws request as it only allows wss

#

Tunnelling and mapping doesn't seem to be the issue, just my Unity code on the transport and setting server/client secrets

drowsy depot
winged elbow
#

What abt the unity transport

winged elbow
drowsy depot
winged elbow
#

Is because I didn't put the ca?

#

Does port 0 have smth to do with unity trying to get the cert

winged elbow
#

@drowsy depot No luck

#

Still tries to connect to wss://mydomain.com:0

#

It'll either connect to that or wss://clientid.discordsays.com:0, both of which are blocked by the CSP

winged elbow
#

I made a forum post in the activities development discord so it's probably more relevant to continue it there so I'm gonna mark this as solved for now, but ty for the help. I'm also trying to see if I can get an official cert instead of self signed

drowsy depot
#

Good luck. Let us know if you get this figured out

winged elbow
#
  function _js_html_utpWebSocketCreate(sockId, addrData, addrSize) {
          var addr = new TextDecoder().decode(HEAPU8.subarray(addrData, addrData + addrSize));
          addr = addr.slice(0, -3);
          var sock = new WebSocket(addr);
#

So literally removing the :0 from the end of the address

#

However every time I build the app I'd have to go and add this line lol

#

I don't know if there's a way to edit wherever unitiy gets this WebGL code from or whatever to find where the :0 is introduced in the binary and patch it, but I guess this will have to do for now

drowsy depot
#

huh, if the unity code is adding that then it might be worth a bug report

winged elbow
#

I'll get a response on the discord activites page and then if they claim that their blocking is intended I'll file a bug report for Unity's end

winged elbow
#

Definetly able to connect from Discord to my computer atleast, but the TLS handshake is still failing at step 1 which is odd because

  1. There is literally only 1 post of that happening
  2. Isn't that the client hello? it's clearly sending a hello
#

This is what my server responds with, super weird

winged elbow
#

Oh nvm, its not even sending the hello when using my server. Strange

#

Seems the server is refusing the socket connection while my echo script allows it, gotta look into that

winged elbow
#

Hm ok, seems to be Unity specific

#

This is with the Unity server running

#

This is with a python script serving the hook running

#

Headers issue maybe?

#

Not sure how I'd fix that, odd

#

Ah, prolly the wss header

#

That's why it's working with ws and not wss

winged elbow
#

Ok really odd, the request is going through and the server gets this messasge so it's not a firewall thing or anything

#
ERR Request failed error="Unable to reach the origin service. The service may be down or it may not be responding to traffic from cloudflared: EOF" connIndex=3

From cloudflared

drowsy depot
#

is the origin service the discord activity in this case?

winged elbow
#

wait no

#

I'm trying to get a look at the headers rn

#

NetworkManager.Singleton.NetworkConfig.EnableNetworkLogs = true; was useless lol

#

I'm gonna try to send the client hello with wscat to localhost:7777 and see if that works

#

Yeah I cant send it through wscat, I guess I need some headers

winged elbow
#

Aaa still no clue
Really odd

drowsy depot
#

Is it working through a regular webgl build?

winged elbow
#

If it's discordproxy then no

#

By target I mean on the component

#

The Unity Transport

#

I have allow remote connections on

drowsy depot
#

I mean if the webgl build can connect to your dedicated server as the target address

winged elbow
#

So basically with default settings + no SetClientSecrets

#

I'm changing it back rn

#

Lemme just confirm it still works

winged elbow
#

@drowsy depot Yep, works if I don't set client secrets and disable encyrption

#

It seems the issue isnt with the Unity Transport but with SetClientSecrets?

#

Well basically if I keep the server name as client.discord.com/foo, it just refuses to connect

winged elbow
winged elbow
#

Through localhost

Headers:
  Sec-WebSocket-Version: 13
  Sec-WebSocket-Key: A9NlCtaZet0lL80Qdv0zAg==
  Connection: Upgrade
  Upgrade: websocket
  Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits  
  Host: localhost:7777

Through discord proxy

Headers:
  Host: mydomain.com
  Accept-Encoding: gzip, br
  Cdn-Loop: cloudflare; loops=1; subreqs=1
  Cf-Connecting-Ip: 2a06:98c0:3600::103
  Cf-Ew-Via: 15
  Cf-Ipcountry: IN
  Cf-Ray: 96a94b6cb6a3937f-MAA
  Cf-Visitor: {"scheme":"https"}
  Cf-Worker: discordsays.com
  Connection: Upgrade
  Sec-Websocket-Key: rpg8XUOqQRaTdf1b3ORptA==
  Sec-Websocket-Version: 13
  Upgrade: websocket
  X-Forwarded-For: 2a06:98c0:3600::103
  X-Forwarded-Proto: https

(cloudflares IP, not mine)

#

I mean I see that theres one thing missing with the Sec-WebSocket-Extensions... dk if that'd matter?

winged elbow
#

@drowsy depot Ok, I got Unity to send the Client hello now: and the server receives it

#

...but still the same issue on the server side

#

Any idea on how to get better logging of traffic on the server end? NetworkManager.Singleton.NetworkConfig.EnableNetworkLogs = true; did nothing

#

13 byte handshake seems small but idk if that's a normal length for UTP first step?

winged elbow
#

Nope the handshake is correct

#

In the working build (where I just use unsecure websockets) I get a 13 byte handshake too

#

except the server responds with the server hello

#

Really no clue why the server refuses to respond? Let me see if theres a good way to monitor incoming traffic to see if my computer gets it at all

drowsy depot
#

You aren't going to get much else from Unity if the handshake is failing

winged elbow
#

Problem is I have no clue to check

winged elbow
# winged elbow

I mean here it shows that it was able to establish a WS connection and send the hello

#

But idk if that means Unity actually got the hello

#

Let me see if there's a way to do that

winged elbow
#

Idk if it means it's receiving the handshake and refusing it or not receiving it or whatever

#

this is really annoying ngl

drowsy depot
#

I've only used webgl with Relay and Distributed authority, so i've never had to deal with certs on a server

winged elbow
#

Yeah fair

#

Thanks for all the help though 🙏 I'll update here if I find a solution

winged elbow
#

Might be a cloudflared issue, think it's unrelated to Unity or Discord... guess I have to see where I can read up on that part

drowsy depot
#

You'll want to check if cloud flare is stripping out SSL or any certificate headers

winged elbow
#

I put the service as ws instead of wss

#

🤦‍♂️

#

Ok, lets see now...

#

Well it seems that may have fixed it and my only issue is certificate issues (I'm getting "certificate is valid for mydomain.com, not localhost"). Not sure if I need a self signed cert on the client side then, I'll see

winged elbow
#

@drowsy depot success!
Yeah, the only thing I did have to do as a hack was to add something in the JS to remove the port

function _js_html_utpWebSocketCreate(sockId, addrData, addrSize) {
          var addr = new TextDecoder().decode(HEAPU8.subarray(addrData, addrData + addrSize));
          function extractUpToSecondColon(str) {
             const parts = str.split(':'); // Split by all colons
             return parts.length >= 2 
               ? parts.slice(0, 2).join(':') // Rejoin first two parts
               : str; // Return original if <2 colons exist
          }
          addr = extractUpToSecondColon(addr);
          var sock = new WebSocket(addr);
#

and yes I diid shamefully use AI to generate an extremely basic JS function
it was 4am and I was tired forgive me lol

#

I'm not sure if I should send a bug report: is it not intended behaviour for Unity to specify the port?

#

If it wants to connect to the server at clientid.discordsays.com at port 7777 shouldn't it target clientid.discordsays.com:7777

#

Which unfortunately discord's CSP rejects

drowsy depot
#

Nice! I wonder if that's the problem when trying to use Relay as well

winged elbow
#

Could be useful in cases like these when using proxys that don't allow nonstandard ports

drowsy depot
#

I would at least submit a Unity support ticket to see what the team has to say

winged elbow
#

Yep, gonna do that now

#

Tysm for the help with the scene loading btw

#

NetworkShow and NetworkHide work very well for entities

drowsy depot
#

And I guess let the Discord folks know as well

winged elbow
#

The only issue is that the geometry takes a sec to load and I fall through the map, so i'm gonna turn all geometry into prefabs

#

and make a script to call InstantiateAsync in OnNetworkSpawn

#

then I can await the geometry properly loading in before re-enabling my CharacterController

#

I guess there's also no reason to split the levels into many prefabs if I'm using InstantiateAsync

winged elbow
#

This is what they had to say