Search Unity

  1. Calling all beginners! Join the FPS Beginners Mods Challenge until December 13.
    Dismiss Notice
  2. It's Cyber Week at the Asset Store!
    Dismiss Notice

UNet and Nat Punchthrough. It can be done!

Discussion in 'Connected Games' started by thegreatzebadiah, Mar 15, 2016.

Thread Status:
Not open for further replies.
  1. thegreatzebadiah

    thegreatzebadiah

    Joined:
    Nov 22, 2012
    Posts:
    784
    NAT-Traversal-for-UNET

    Overview
    An example implementation of NAT Traversal combined with Unity's UNet HLAPI. Attempts to establish direct connections between players using a combination of NAT Punchthrough and automatic port forwarding. Falls back to UNET's relay servers only when absolutely necessary. When initially connecting the first connection to succeed is used, but if a direct connection succeeds after a relay connection is already established the direct connection will replace the relay connection.

    *Make sure to take a look at the README.*

    But Why?
    The primary motivation for creating this was so that I could be less dependent on Unity's relay servers. For one, they are bandwidth restricted, and they seem to introduce some pretty high latency. Plus it's just one more point of failure that us lowly developers have absolutely no control over. This solution should mean that connecting through Unity's relay servers is almost never necessary.

    Requirements
    Unity 5.2 or above
    RakNet and Open.NAT dll's are included for windows but you'll have to compiler your own for Mac / Linux

    Known Issues
    RakNet doesn't work with web sockets, so no web builds.
    Needs lots of testing

    Download
    NAT Traversal for UNET

    Other
    If you are just looking for NAT punch-through without all the other bells and whistles I've got a simpler example here: NATPunchthroughClient

    I'm putting this out there for anyone to use. I'd really appreciate any feedback / testing that the community can provide. Another set of eyes always helps and I'm really not positive I've got everything set up 100% correctly. If you download the project and can't get it working please report back here and make sure to mention the router models involved. RakNet is a pretty mature library so if something goes wrong it's probably a problem in my code and probably something easily fixed, or you just happen to have one of the few router setups that punchthrough doesn't work on.

    You are welcome (and encouraged) to submit pull requests to the repo if you find yourself adding to or extending the functionality in useful ways.

    Thank you!
     
    Last edited: Mar 18, 2016
    bboysil, moco2k, iamnotseanr and 2 others like this.
  2. Imtnt

    Imtnt

    Joined:
    Nov 13, 2013
    Posts:
    8
    A version that used the relay as a fallback would be amazing! I would also love to contribute to this, as NAT punching should be in UNET!
     
    thegreatzebadiah likes this.
  3. thegreatzebadiah

    thegreatzebadiah

    Joined:
    Nov 22, 2012
    Posts:
    784
    Feel free to clone the repo and submit a pull request if you come up with any good changes / improvements. I'm open to collaboration.

    I might see if I can put together a more complete example with port forwarding tomorrow, but no promises. I've got to work on the actual game at some point you know!

    If you wanted to try and implement the fallback to relay yourself that would honestly be amazing. No pressure or anything though ;p The hard part would be creating a router setup where punchthrough fails so that you can properly test that the relay works when punchthrough doesn't.
     
  4. gagwieg

    gagwieg

    Joined:
    Dec 22, 2015
    Posts:
    3
    Hello,
    I would like to ask if i can use google services real multiplayer to MatchMaking and let use uNet HLAPI to Mange the game?
     
  5. thegreatzebadiah

    thegreatzebadiah

    Joined:
    Nov 22, 2012
    Posts:
    784
    I'm not familiar with that service in particular but in general it doesn't really matter how you do your matchmaking, as long as you somehow pass around the external and internal IP of the host to connect to. If using the NATPunchthroughClient you also need to include the raknet GUID. In the example here I do it by including it in the match name that I create on UNet but I've also done it before using a custom php script and a database, or via the steam api. As long as you've got some way to pass the connection info it's all gravy.
     
  6. Bmandk

    Bmandk

    Joined:
    Aug 18, 2012
    Posts:
    62
    Holy S*** haha, I was just googling around for NAT punchthrough (again), and found my own post I posted last year when UNET came out. Then I saw that you had replied, YESTERDAY, with this! What are the odds!? Thanks a lot, I will definitely try this out in the near future!
     
    thegreatzebadiah likes this.
  7. GalacticGlum

    GalacticGlum

    Joined:
    Jul 30, 2015
    Posts:
    29
    How would I go about implementing RakNet's relay server so I don't have to use Unity's paid (and expensive) relay servers?
     
    thegreatzebadiah likes this.
  8. thegreatzebadiah

    thegreatzebadiah

    Joined:
    Nov 22, 2012
    Posts:
    784
    I'm honestly not sure, I only theorized that it may be possible. I have no plan of implementing that functionality myself because I think NAT Traversal is going to handle the vast majority of cases anyway. That being said, you are more than welcome to contribute to the project on github. The ability to use self hosted raknet relays would be amazing. There is some advantage to not hosting your own though, like not having to worry about having servers physically spread all over the world or load balancing / connecting to closest server.
     
  9. larku

    larku

    Joined:
    Mar 14, 2013
    Posts:
    1,412
    Note that using RakNet will lock you out of using Web builds (and any other platforms that don't allow real sockets and pthreads).

    I use custom RakNet networking and really like it, but it comes with some baggage.
     
    thegreatzebadiah likes this.
  10. GalacticGlum

    GalacticGlum

    Joined:
    Jul 30, 2015
    Posts:
    29
    Thanks guys! I've decided not to try to implement relay server, I'll be contributing to the project though (direct connection -> port forward -> NAT Punchthrough).
     
    thegreatzebadiah and moco2k like this.
  11. moco2k

    moco2k

    Joined:
    Apr 29, 2015
    Posts:
    289
    Thumbs up. It would be awesome if you guys could manage to develop some kind of stable drop-in solution for this.
     
    thegreatzebadiah likes this.
  12. thegreatzebadiah

    thegreatzebadiah

    Joined:
    Nov 22, 2012
    Posts:
    784
    I think I just got all this working. Direct connect, punch-through, and relay connections are all started immediately. The first connection to succeed is used. If for some reason a relay connection is made first but then a direct connection is later established via punch-through the direct connection replaces the relay connection seamlessly. This means that players can connect as soon as possible but they won't be stuck sending data through the relay when a direct connection is possible just because punch-through took a little too long. Best of both worlds!

    Oh I've also got automatic port forwarding implemented via Open.NAT.

    I'll post an update as soon as I get the code cleaned up a bit.
     
  13. GalacticGlum

    GalacticGlum

    Joined:
    Jul 30, 2015
    Posts:
    29
    Awesome! I'm just getting started on my version :D

    How do you check if the direct connection, NAT punchthrough connection, or Open.NAT connection didn't work? Is it the same way we'd check to see if the player is connected with standard UNet?
     
  14. thegreatzebadiah

    thegreatzebadiah

    Joined:
    Nov 22, 2012
    Posts:
    784
    I just posted an updated version here with all the promised features :)

    http://forum.unity3d.com/threads/nat-traversal-with-unet.392318/

    Ummm, right now I'm not doing anything with failed connections. Definitely something that should be looked in to. Right now I think OnClientError will be called on the NetworkManager if the relay connection fails but that's it. Ideally we'd want to catch the errors from the other clients as well. We'll know connection has really failed when we've received errors from all three.
     
    GrymmyD likes this.
  15. GalacticGlum

    GalacticGlum

    Joined:
    Jul 30, 2015
    Posts:
    29
  16. GrymmyD

    GrymmyD

    Joined:
    Dec 2, 2015
    Posts:
    42
    I will get to playing with this as soon as I am able and will provide feedback.
     
  17. thegreatzebadiah

    thegreatzebadiah

    Joined:
    Nov 22, 2012
    Posts:
    784
    Just letting everyone know that my other thread was closed by a mod. Here is the reason given (emphasis mine):

    I sent some probably unnecessarily angry messages back because I think both threads are pretty relevant. This one being the simplest possibly example of NAT Punchthrough and the other being full NAT Traversal (same reason I created separate github repos). Hopefully they'll unlock it, but probably not so I'm updating all of the links and the information at the top of this thread to point to the newest latest greatest stuff. I'll make sure to include a link to the punch-through only example that this thread was originally about because someone may still find it useful.
     
    Pedro-Paternostro likes this.
  18. SaraCecilia

    SaraCecilia

    Joined:
    Jul 9, 2014
    Posts:
    675
    It's actually really not cool that you are taking a private conversation and publishing it live. Please be respectful of this.
     
    GameDevCouple_I likes this.
Thread Status:
Not open for further replies.