I'm feeling defeated after many different approaches and researching how to UDP hole punch in GM:S. Has anyone had any success with this using standard GM:S networking functions, and not relying on extensions like 39 DLL or C++ servers? I've read all sorts of older posts, but I am curious if someone has had succeeded with this using the stock networking functions.
I am using a combination of UDP and TCP functions to coordinate online functionality for my current project. So far I have built a sign up / log in menu system. Knowing how GM:S locks up for several seconds when attempting a dead TCP socket connection, I thought I would be smart and have the client ping the server first via a UDP message and only connect when it hears something back. The problem is that unless the client has port forwarded a specific port for listening for the server's UDP return message, nothing will ever return and the connection never happens.
As an example, here is how I have approached the situation and say we map the following ports (illustrative purposes only):
- Client_UDP = 123
- Server_UDP = 456
- Server_TCP = 789
When client attempts connection, have them create a UDP server listening on port 123. Knowing the server is listening for UDP messages on port 456, send message to this port. Server hears message and replies to client via port 123. Client hears UDP reply and creates TCP socket looking for server port 789.
This is fine and all, but as I said before, unless the client has port forwarded port 123, the message will never get back. I would like (if possible) not to burden the player with having to port forward, but it would be awesome to get the quick UDP feedback before attempting a TCP connection.
While debugging on the server side, using the async_load map to look up incoming IPs and ports, I can see the ephemeral port used by the client (usually in the range 49152 through 65535 as expected). One problem is that if the server responds directly to this port, the message will not make it back to the client. I'm assuming that for whatever reason it doesn't translate back to the original port (123) or the client is still listening on 123 and the returned message is ignored.
This is pretty much where I am stuck for now, hence why I am curious to know if any one has figured a way around this.
I have a theory that if there was a way to get the ephemeral port on the client side, you could create a new UDP server on the client's end to listen for the server's return message assuming everything happens before the port closes. I'm currently looking for a JSON API or something that I can ping which would return the ephemeral port since the HTTP functions don't need port forwarding.