Search Unity

NAT Traversal - Automatic port forwarding, punch-through, and more!

Discussion in 'Assets and Asset Store' started by thegreatzebadiah, Apr 5, 2016.

  1. thegreatzebadiah

    thegreatzebadiah

    Joined:
    Nov 22, 2012
    Posts:
    836
    This is where IPv6 confuses me. I would think the external IPv6 address would actually be the address of your specific computer and not your router since the idea behind IPv6 is that every computer should be directly routable. None of this NAT nonsense should even be necessary when connecting to an IPv6 host. Maybe your ISP and router support ipv6 so the router is assigned an ipv6 address but the individual computers on the LAN aren't actually using an IPv6 connection for whatever reason? Maybe I should only attempt an ipv6 connection when the host has both an internal and external IPv6 addresses? Just throwing out random thoughts at this point...
     
  2. thegreatzebadiah

    thegreatzebadiah

    Joined:
    Nov 22, 2012
    Posts:
    836
  3. robochase

    robochase

    Joined:
    Mar 1, 2014
    Posts:
    244
    interesting...i'm on 5.3.5, and i can't really upgrade to 5.4+ currently. i do see there's a 5.3.6 & 7 that i could try out too. looking at the patch notes, there are some IPv6 fixes for both of those versions. I'll also try upgrading tonight and see if that improves my success rates.

    i confess i don't know much about the whole LAN/external ip thing either. i just know i can access devices on my LAN via 10.0.0.x, but if i go to whatismyip.com, it's definitely showing an IPv6 address.
     
  4. Doghelmer

    Doghelmer

    Joined:
    Aug 30, 2014
    Posts:
    120
    So, this was indeed entirely my fault. The issue was occurring because I had set my game's timescale to 0 shortly after beginning the game. The facilitator would start connecting, but it wouldn't be able to finish. That's all there is to it. I had assumed I wasn't supposed to see "connected to facilitator" until I had attempted to start/join a game, which obviously is not the case.
     
    thegreatzebadiah likes this.
  5. KaldrisRelm

    KaldrisRelm

    Joined:
    Mar 8, 2014
    Posts:
    10
    Hi @thegreatzebadiah,

    I've been working on my side with the NATLobbyManager in your most recent update, so I may be able to provide the issue @Eiseno was encountering, granted mine may end up being different

    This happens in NATLobbyManager.cs - Line 377(I think):
    Code (CSharp):
    1. NetworkServer.AddPlayerForConnection(conn, newLobbyGameObject, playerControllerId);
    The above is encountered in a copy of my project, so it could be something unique to my own situation. I'm trying to replicate the same using Unity's 'Network Meteoroid' Asset (Link), but am having some issues getting the Facilitator to acknowledge my game creation attempt.

    Ideally if I can get this going I can give you a project that will let you run both NATLobby & Standard Lobby side by side.
     
  6. thegreatzebadiah

    thegreatzebadiah

    Joined:
    Nov 22, 2012
    Posts:
    836
    @KaldrisRelm That error message is from Unity's LobbyPlayer and not the NATLobbyPlayer so I would guess that is the problem. LobbyPlayer is not compatible with the NATLobbyManager, you will have to use NATLobbyPlayer instead but it's almost the same exact thing.
     
  7. KaldrisRelm

    KaldrisRelm

    Joined:
    Mar 8, 2014
    Posts:
    10
    Hi @thegreatzebadia,

    I agree with you, the error message is from Unity's LobbyPlayer. The AddPlayerForConnection() takes 'newLobbyGameObject' as a parameter, and it uses that GameObject to assign connection details for the player (Edit: I think) . I think the problem though is that AddPlayerForConnection() is looking for LobbyPlayer, however it won't find that script as the 'newLobbyGameObject' is set to a prefab with NATLobbyPlayer instead.
     
  8. thegreatzebadiah

    thegreatzebadiah

    Joined:
    Nov 22, 2012
    Posts:
    836
    Unless I'm mistaken AddPlayerForConnection is just looking for a Player prefab. I don't think it needs to be a LobbyPlayer, nor should it be. Are you absolutely positive your Player prefab has a NATLobbyPlayer component and not a lingering LobbyPlayer component.

    I don't think this is quite right. The code that is printing that error is from the LobbyPlayer component, so a LobbyPlayer is definitely being spawned. The problem is that the LobbyPlayer then looks for a NetworkLobbyManager and (understandly) doesn't find one.
     
    Last edited: Jan 18, 2017
  9. KaldrisRelm

    KaldrisRelm

    Joined:
    Mar 8, 2014
    Posts:
    10
    On review I read the error message completely wrong, apologies for the confusion. I haven't been able to replicate the same error using the Network Meteoroid as a base, so it's probably a better idea to consider the error I found to be from something I did wrong, rather then anything with the NAT Traversal scripts.

    Entertainingly, in trying to replicate using the Network Meteoroid I've at the same spot as back in November, where the game immediately transitions to the 'Play Scene' after creating the lobby. I'm making progress, but probably in the wrong direction.
     
  10. deliinteractive

    deliinteractive

    Joined:
    Oct 8, 2014
    Posts:
    25
    Oh boy do I feel ya on the IPv6 stuff. I really don't know what I'm doing either. Thanks a bunch for the code snippets though! This will be really really useful stuff, I'm sure. I'll get to work on overriding that and get back to you.

    This does give me more questions, though. For instance, is PickCorrectAddressToConnectTo() called when attempting the relay connection? I have not been able to understand why after enabling the relay this hasn't alleviated our connection problems. All of the initial connections between myself and the IPv6 dev are by relay, get established, and then fail to cause the expected scene changes or object spawning one would expect to see after a successful connection. Soon the relay connection simply drops. So what can I do to ensure that when the host has an IPv6 address, the correct host IP is being handed over to Unity's relays? Once again, thanks so much, and sorry for making extra work for you. However, I think we'll all be happier that we found these problems now before Grabbles or We Need to Go Deeper have released, eh?
     
  11. robochase

    robochase

    Joined:
    Mar 1, 2014
    Posts:
    244
    @thegreatzebadiah
    ok, so i got to test my problem scenario again - an IPv4 host i can't connect to as an IPv6 client in the Example scene. punchthrough still doesn't work :(

    i upgraded unity from 5.3.5 to 5.3.7. also logging out the results of pickCorrectAddressToConnectTo, and it's definitely picking out the dood's IPv4 address correctly.

    HOWEVER...
    we tried an experiment where the host had 'Connect Directly' and 'Connect Punchthrough' checked, and the client had all 3 options checked, including 'Connect Relay'.

    this scenario worked, but i need a little insight into what is actually happening here. in the client logs, i see some prints about it connecting to the relay server, but i also see some prints about it setting up punchthrough holes and stuff. when it's finally done, we both see each other's noble whale moving around. i go to check the unity multiplayer admin panel for my game, and it's showing 0 CCU (been refreshing the admin page frequently for 5 minutes, it's always 0 ccu).....so what the heck is happening here? is it actually working?

    if the host doesn't have 'Connect Relay' checked when they click host, are they ever even allowed to actually connect to the relay server at all? i would expect not, unless it's somehow instructed to via the facilitator or something. am i somehow massaging the code to go down the correct series of paths by mismatching my connection toggles? is the unity dashboard just incorrectly displaying the wrong CCUs?

    On an unrelated note that others may find helpful - i had been having trouble even directly connecting to this particular host, but we managed to sort that out as a potential router bug. He was setting up a single port forward of 7777 which wasn't working at all. he changed it to a port forwarding range of 7777 to 7777, and that seems to work no problem. this is kind of a huge relief to me, because at least now i can give players good instructions on what they can try in case punchthrough isn't working for them for some reason.
     
  12. thegreatzebadiah

    thegreatzebadiah

    Joined:
    Nov 22, 2012
    Posts:
    836
    I believe it's just connecting via relay. The host will be hosting via relay as long as useUnityMatchmaking is checked even if "Connect Relay" isn't checked on the host. But you are showing 0 ccu so idk. It could be something magical happening when client thinks it is connecting via relay that makes the ipv6 connection start working. If you can get me the full logs I can probably figure out what kind of connection was actually made.
     
  13. thegreatzebadiah

    thegreatzebadiah

    Joined:
    Nov 22, 2012
    Posts:
    836
    PickCorrectAddressToConnectTo() is only called for direct connections.
     
  14. Doghelmer

    Doghelmer

    Joined:
    Aug 30, 2014
    Posts:
    120
    @thegreatzebadiah
    I added this plugin to my game a few days ago, and my users alerted me to a couple of issues - one of which I can reproduce consistently, and the other of which is a bit more inconsistent.

    ISSUE 1:
    I've noticed that when connecting via NAT Punchthrough, the hostid of the connection increases by 1 each time a new person connects (or quits the game and reconnects). When this number reaches 16, the server shows the following error message:
    Code (csharp):
    1. maximum hosts cannot exceed {16}
    When this occurs, no new players can join the game. I've tested with direct connect and relays, and the hostid does not appear to increase in those cases.

    ISSUE 2:
    There are times when a client joins the game, and is immediately disconnected... sort of. On the server, OnServerDisconnect is called as soon as a client joins. However, the client is still able to receive messages from the server after this has taken place. They will actually receive the message "xxxx has left the game" as soon as they enter the game -- a message that is called via ClientRPC after a client has disconnected and their avatar has been destroyed. So I'm left with a server who thinks the client has disconnected, and a client who is actually connected.

    Once this happens, it will be impossible for that client (or other clients) to join the game, as the same issue will keep happening.

    There are times when I can reproduce the issue very consistently, typically by disconnecting and reconnecting from the server 3 or 4 times. Other times, I can't reproduce it at all. I think (though not entirely positive due to the inconsistency) that this is only occurring with NAT Punchthrough. I wasn't able to reproduce the issue with the example files, but again, that could be due to the inconsistency.

    I'm not getting any unusual error messages or hints in my log as to why people are being immediately kicked. Just OnServerDisconnect being called. Sorry for the vagueness here -- does any of this sound familiar? And is there a way of determining if a NetworkConnection is indeed, actually disconnected? (oddly, the variable "NetworkConnection.isConnected" is not it)
     
    Last edited: Jan 18, 2017
    boxels likes this.
  15. clintonb

    clintonb

    Joined:
    Dec 14, 2013
    Posts:
    15
    Hello, @thegreatzebadiah

    This looks like a great asset.

    My team and I are new to UNet (but have used other multiplayer systems in the past), but only wanted to use it if we could get the speed of direct connects, which this asset provides.

    We had difficulty figuring out how to make the Example scene work. Finally, we realized we needed to have Unity Multiplayer turned on so that when direct/punch-through connections were made, they knew what to join. Explaining that in the tutorial video/docs will likely help other UNet newbies using this.

    I'd like to put in a plug for making this work on Android and iOS devices (but, will agree, that the thought of cross-compiling a significant C++ codebase is daunting, and I don't know anything about SWIG myself.)

    I'd also like to suggest that the example scene shows how players are connected ('You are connected using: punch-through and relay').

    Thanks for all the great work that has gone into this.
     
  16. TCROC

    TCROC

    Joined:
    Aug 15, 2015
    Posts:
    230
    @thegreatzebadiah Hey, have you had any time to look into Windows Store compatibly? I was wondering how that is looking.

    @clintonb Hey, if you create a plugin to make this work on the Android and iOS devices, is there any chance that you could share it with us? It has been a much wanted feature for many people on this forum including myself.
     
    Last edited: Jan 19, 2017
  17. deliinteractive

    deliinteractive

    Joined:
    Oct 8, 2014
    Posts:
    25
    @thegreatzebadiah Yikes! I thought the relays were a sure-fire success. What are we passing over to the relays, then? I've noticed that the only connections which even establish with our IPv6 dev are by relay, but as I stated, the scene doesn't change and the relay times out after 10 attempts (despite stating that it has connected), which takes ~20 seconds or so. I'm A-okay with the IPv6 support the asset has right now if I can just get the relays working to cover our IPv6 cases.
     
    Last edited: Jan 20, 2017
  18. clintonb

    clintonb

    Joined:
    Dec 14, 2013
    Posts:
    15
    Hi @TCROC,

    I think it is unlikely that I'll get the plugin built, but if by some chance I do, I'll ask for permission to share it.
     
  19. TCROC

    TCROC

    Joined:
    Aug 15, 2015
    Posts:
    230
    Thanks @clintonb! I'm sure he won't mind. I recently implemented a voice chat plugin with NAT Traversal and shared it with everyone in the forum. I just didn't include the NAT Traversal plugin in the project and made it so they had to import NAT Traversal seperately.
     
    thegreatzebadiah likes this.
  20. KaldrisRelm

    KaldrisRelm

    Joined:
    Mar 8, 2014
    Posts:
    10
    @thegreatzebadiah - I was able to finally stop the game moving immediately to the 'Play Scene' and completely skipping out on the Lobby section. Best I can tell it seemed to be an issue with the 'Play Scene' itself, I needed to save the scene under a different name, add that to the 'Build Settings', then swap the 'Play Scene' to this new scene name - though this may have just been coincidental.

    I wanted to build a small project to show the above for you but it seems I can no longer replicate the issue anymore on a brand new project either, Ghost in the Machine I swear...

    Besides this problem (not counting stupid mistakes I made earlier) everything else about the Lobby systems works quite well. I'm building in the rest of my custom functionality currently and it's pretty much all been drag and dropping without any further issues.
     
    thegreatzebadiah likes this.
  21. robochase

    robochase

    Joined:
    Mar 1, 2014
    Posts:
    244
    heh, of course i can't repro this now. the unity dashboard is reliably reporting 2 CCU today, so maybe the dashboard was just bugging out the other day :/

    anyways, @thegreatzebadiah - i was poking around the internet this morning, reading about awesomenauts' networking, and i stumbled upon a dev blog post about relay servers (http://joostdevblog.blogspot.com/2014/09/relay-servers.html) awesomenauts doesn't use relay servers, and the article mentions one interesting tidbit about their approach when connecting players -

    now, their game is totally peer to peer - each peer in the game attempts to connect to each other instead of Unet's typical pattern where all the client peers connect just to the host, but never to each other. so in awesomenauts, if two players can't connect to each other, but they can connect to a 3rd player, that 3rd player ends up becoming a mini relay server of sorts for them, forwarding packets to each other.

    so my question to you - how hard would it be to build a peer to peer layer into the nat traversal plugin or on top of the plugin? i'm guessing without access to the source code, i wouldn't be able to build this on top of your plugin. so how hard do you think it would be to add it to the plugin? i think the main thing i'd need the plugin to solve is to provide a way for clients to connect to each other relying on your nat traversal tech. or maybe this is already possible if you run multiple instances of a NetworkManager? that sounds really messy and i'm guessing a lot of the static function calls around NetworkServer and such would give you tons of issues.

    i'd been looking into the low level api some, and it seems like it wouldn't be ....super complicated to build a simple p2p system alongside the HLAPI. another approach - i noticed that it's possible to extend the NetworkConnection class and tell the NetworkManager to use this version instead of NetworkConnection (https://docs.unity3d.com/ScriptReference/Networking.NetworkServer-networkConnectionClass.html). From there, you could override the TransportReceive and TransportSend functions to possibly pass along the data to another client if you needed to. or simply have your parallel p2p system call TransportReceive on the corresponding network connection object. Very hypothetical stuff, and probably not super simple. But it's very nice to sever ties with Unity's relay server if possible.
     
  22. pragmascript

    pragmascript

    Joined:
    Dec 31, 2010
    Posts:
    107
    Hello :) would this also work for the LLAPI? (I'm currently using the LLAPI for my project)
    Sorry if this has been asked before
     
  23. ReignOfDave

    ReignOfDave

    Joined:
    Oct 22, 2015
    Posts:
    51
    So i am using unity 5.5 and when i host a game it seems to go well as the player gets spawned in but if i try and join the server as a client it just says match list is empty.
     
  24. thegreatzebadiah

    thegreatzebadiah

    Joined:
    Nov 22, 2012
    Posts:
    836
    @GamerDave Do you have "Use Unity Matchmaking" checked on the host?
     
  25. TCROC

    TCROC

    Joined:
    Aug 15, 2015
    Posts:
    230
  26. thegreatzebadiah

    thegreatzebadiah

    Joined:
    Nov 22, 2012
    Posts:
    836
    Yep, there is a stripped down example scene (ExampleNATHelperOnly) that shows how to use the punch-through and port forwarding "manually" which should make it pretty easy to tie into the LLAPI.
     
    pragmascript likes this.
  27. thegreatzebadiah

    thegreatzebadiah

    Joined:
    Nov 22, 2012
    Posts:
    836
    No progress sorry. To be honest it's not my highest priority. I've got a lot on my plate at the moment so I'm trying to stick to strictly bug fixes.
     
  28. thegreatzebadiah

    thegreatzebadiah

    Joined:
    Nov 22, 2012
    Posts:
    836
    My answer to you is...I really don't know. That's definitely way beyond the scope of anything I personally want to build into the plugin but I don't think it would be impossible to build on top of it.

    I think you're probably on the right path here, that's exactly what I do for punchthrough connections.

    I'd love to hear if you get something like this working. It seems really cool, and I totally agree it would be great to completely get away from the relays.
     
  29. thegreatzebadiah

    thegreatzebadiah

    Joined:
    Nov 22, 2012
    Posts:
    836
    That's a great idea. I'll add it to my TODO list.
     
  30. thegreatzebadiah

    thegreatzebadiah

    Joined:
    Nov 22, 2012
    Posts:
    836
    I'm looking into this. Seems straightforward at least.

    This sounds like a headache. If you can confirm that it can be replicated in the Example scene it would definitely help.

    On a non-host client you can try checking directClient.isConnected, punchthroughClient.isConnected, and relayClient.isConnected. Really though on both client and host just checking client.isConnected should be enough.
     
  31. TCROC

    TCROC

    Joined:
    Aug 15, 2015
    Posts:
    230
    Ok well when u get a chance it will be greatly appreciated!
     
  32. thegreatzebadiah

    thegreatzebadiah

    Joined:
    Nov 22, 2012
    Posts:
    836
    @Doghelmer I just fixed the maximum host id issue. It should show up on the store in a week or so (usually less).

    @clintonb I added this to the latest build. Thanks for the suggestion.
     
  33. Doghelmer

    Doghelmer

    Joined:
    Aug 30, 2014
    Posts:
    120
    Thank you! I haven't had a chance to look further into the other issue yet, but I'll see what I can come up with when I get the time.
     
  34. WaaghMan

    WaaghMan

    Joined:
    Jan 27, 2014
    Posts:
    245
    Hi, it's been a while (which is a good thing actually!).

    We received a log from an user that showed really strange things.

    We're currently only sharing NetworkManager.externalIP and NetworkManager.hostInternalIP in the lobby data, so players should only use IPv4 to connect to hosts (we did this because we were having issues), right? We found in the log of one user that NetworkManager.externalIP showed an IPv6 format string, and the client would not properly connect because of that (fortunately it managed to connect through Relay).

    Is this an expected behavior (externalIP having IPv6 addresses)? I should add that I'm not sure we are using the latest version of the plugin, maybe we're one version behind.
     
  35. omanak

    omanak

    Joined:
    Mar 1, 2013
    Posts:
    4
    Hey, I'm currently working on a unity project. I'm using the low-level client Network Client connect that takes an ip address and a port. It all works locally, but not online. I've got external ips. But it still fails, does this sound like a port mapping issue and would your nat helper file, well, help?
     
  36. thegreatzebadiah

    thegreatzebadiah

    Joined:
    Nov 22, 2012
    Posts:
    836
    @omanak
    definitely sounds like a nat issue. port mapping and port forwarding would both help, and yeah the NATHelper can help you with that. It will be a little trickier using a NetworkClient directly rather than using the NetworkManager but it's definitely possible since that's exactly what the NetworkManager is doing behind the scenes.

    @WaaghMan That is definitely not intended behaviour. I'm really not even sure how that's possible. Even if the user was on an ipv6 only network (highly unlikely) I would expect the externalIP to just be blank. Upgrading to the latest version definitely could help though, I've been fiddling with ipv6 stuff pretty much every update trying to get it to work right.
     
    omanak likes this.
  37. omanak

    omanak

    Joined:
    Mar 1, 2013
    Posts:
    4
    Thanks for the info, sorry one last question. Would I need a facilitator for either the port forwarding or mapping?
     
  38. thegreatzebadiah

    thegreatzebadiah

    Joined:
    Nov 22, 2012
    Posts:
    836
    @omanak you'll need the Facilitator for mapping only.
     
    omanak likes this.
  39. Deleted User

    Deleted User

    Guest

    @thegreatzebadiah Hello, have some kind of weird problem and can't recognize it's my fault or maybe bug. If I connect to any game and after will try to host game, scene will load but player doesn't respawn and I will get this log. Thanks! upload_2017-2-3_23-15-17.png upload_2017-2-3_23-43-47.png
     
    Last edited by a moderator: Feb 3, 2017
  40. TheMadChemist

    TheMadChemist

    Joined:
    Mar 18, 2015
    Posts:
    10
    I've just installed this add-on and the setup appears to be simple enough. I have a server with a facilitator and it connects just fine. There seems to be a problem when enabling the unet matchmaking; I've attached the error log trace below. It occurs with both my custom manager and the simplified custom manager you provide in the example. Any idea what is being passed that might come up as null on the native createMatch call? Thanks for your time.

    Code (csharp):
    1.  
    2. Parameter name: s
    3. System.Text.Encoding.GetBytes (System.String s) (at /Users/builduser/buildslave/mono/build/mcs/class/corlib/System.Text/Encoding.cs:268)
    4. UnityEngine.WWWForm.AddField (System.String fieldName, System.String value, System.Text.Encoding e) (at C:/buildslave/unity/build/artifacts/generated/common/runtime/UtilsBindings.gen.cs:566)
    5. UnityEngine.WWWForm.AddField (System.String fieldName, System.String value) (at C:/buildslave/unity/build/artifacts/generated/common/runtime/UtilsBindings.gen.cs:560)
    6. UnityEngine.Networking.Match.NetworkMatch.CreateMatch (UnityEngine.Networking.Match.CreateMatchRequest req, UnityEngine.Networking.Match.DataResponseDelegate`1 callback) (at C:/buildslave/unity/build/Runtime/Networking/Managed/MatchMakingClient.cs:166)
    7. UnityEngine.Networking.Match.NetworkMatch.CreateMatch (System.String matchName, UInt32 matchSize, Boolean matchAdvertise, System.String matchPassword, System.String publicClientAddress, System.String privateClientAddress, Int32 eloScoreForMatch, Int32 requestDomain, UnityEngine.Networking.Match.DataResponseDelegate`1 callback) (at C:/buildslave/unity/build/Runtime/Networking/Managed/MatchMakingClient.cs:139)
    8. NATTraversal.NetworkManager+<StartHostAsync>d__61.MoveNext ()
    9. UnityEngine.SetupCoroutine.InvokeMoveNext (IEnumerator enumerator, IntPtr returnValueAddress) (at C:/buildslave/unity/build/Runtime/Export/Coroutines.cs:17)
    10.  

    EDIT:
    So I've resolved the issues. I noticed it also caused the editor to crash on startup and traced an error to a lavasoft dll. Something called "Ad Aware Web Companion", or something like that, had installed itself and was causing a range of networking issues on my computer. I already use Putty, so I think it was the filezilla installer that added it. Once that was removed, worked like a charm.
     
    Last edited: Feb 4, 2017
    thegreatzebadiah likes this.
  41. pengee

    pengee

    Joined:
    Jan 16, 2015
    Posts:
    1
    Having an odd problem with this. Everything seems to work. Connected clients show NetworkClient.active is true but the NetworkManager.isNetworkActive, which should return the state of NetworkServer.active or NetworkClient.active is returning false, only for clients.
     
  42. omanak

    omanak

    Joined:
    Mar 1, 2013
    Posts:
    4
    Hi, picked up the plugin. Seems to work although it won't detect the NAT on some networks. Sorry I'm kind of new to networking. Here is my understanding, if I can't find the NAT and that isn't working. Then my only alternative is to go the full NAT punchthrough route? Also cheers, I'm a lot closer to cracking this than I was :)

    UPDATE:
    Tried using punch-through. Got everything working up to the point:
    LogManager.DebugLog(LogManager.Log.Network,"Start a socket on " + clientPort + " and connect to the server on " + serverPort);
    m_Client_Info.m_Client_Object.Connect(hostIP, serverPort);

    This still doesn't appear to connect to the client. As I said the portmapping functions seems to work if it can detect the NAT. Or could it be that the connect is happening before the NetworkServer.Listen is called?
     
    Last edited: Feb 7, 2017
  43. Doghelmer

    Doghelmer

    Joined:
    Aug 30, 2014
    Posts:
    120
    This question isn't specifically related to NAT Traversal, but I've asked this a few times elsewhere to little help and it's getting to be a real problem, as my game is launching next month. If this sounds familiar to anyone, I'd really appreciate the input. Anyways:

    My game tends to have a lot of objects with NetworkIdentities in the scene at any given time -- potentially upwards of 100.

    When a client joins a game in progress, the hierarchy view indicates that these objects are spawned very quickly on the client side, even at slow connection speeds.

    However, if the server changes the scene, causing the client to connect to this new scene, the objects are spawned MUCH more slowly on the client side -- to the point where it can take upwards of 30 seconds for everything to be spawned at 100 ms of lag (using the network simulator). I can see the objects being spawned in one at a time, or sometimes in small groups.

    It doesn't make any much sense to me that the object syncing is working so well in one scenario, and so poorly in the other. And the slowness seems to get even worse when the scene changes for a second time.

    I considered that this might have something to do with not all of the objects being spawned on the server side before the client joined (the game is procedurally generated), but this does not seem to be the case. I can set the client to be "ready" long after the scene has fully loaded, and objects are still loaded slowly. Also worth noting, I've tested this all using the network simulator, and also in a real-world environment with a player who had a slow connection speed. Things seem to function the same way in both scenarios, so it's definitely not a case of the network simulator acting wonky.

    Any ideas on what might be causing this?
     
    boxels likes this.
  44. KaZe_

    KaZe_

    Joined:
    May 13, 2015
    Posts:
    12
    Hello @thegreatzebadiah ,

    I recently tried to integrate the plugin into my game. The problem is, opening the Nat Helper example you guys gave and with 2 computers connected in 2 completely different networks ( one is using my phone's hotspot and the other is using a broadband connection ) I receive the following error all the time:

    NATHelper: Unexpected raknet message received: ID_NAT_PUNCHTHROUGH_FAILED

    What could this be?

    ------------------------------------------------------
    Update:

    Since yesterday messing around with the plugin and there's something very interesting ( and maybe bad ) going on.

    At the moment I'm just using the NatHelper. I have my own matchmaking system and I want the players to connect to each other so one will be a "server" and the other a "client" ( I didn't chose this :) ). As I said I'm testing with 2 different machines, one connected to my phone's 4G and another connected to a normal broadband service. I also have my facilitator hosted in a server and being accessed by both machines. When I run the following code in my networkmanager:

    Code (CSharp):
    1.  
    2. void Start()
    3. {
    4.         natHelper = GetComponent<NATHelper>();
    5.         natHelper.findNatDevice();
    6.  
    7.         natHelper.OnDoneConnectingToFacilitator += OnDoneConnectToTheFacilitator;
    8.  
    9.         // Connect to Facilitator for punchthrough
    10.         natHelper.StartCoroutine(natHelper.connectToNATFacilitator());
    11. }
    12.  
    13. void OnDoneConnectToTheFacilitator(ulong myGUID)
    14. {
    15.         Debug.Log("Facilitator is connected. GUID: " + myGUID);
    16.      
    17.         natHelper.mapPort(directConnectPort, directConnectPort, Protocol.Both, "Game Initialisation", onPortMappingDone);
    18. }
    One of the machines perform the Punchthrough normally, and the other gives me the following warning: NATHelper: NAT Device not found. After my matchmaking give's me a match I send to the peers the ip and GUID to connect, try to punch a hole from client to server while the server waits for it and the client never succeed.

    Some details:
    - I'm only using the NAT Helper. I'm not extending NATTraversal.NetworkManager in my network manager. Is it mandatory?
    - I'm using a specific port for the connection. I saw that sometimes the NatHelper maps the hole into different ports, Does the forwarding ports really open the specific port I assigned it to?

    Regards,

    Luiz
     
    Last edited: Feb 16, 2017
  45. thegreatzebadiah

    thegreatzebadiah

    Joined:
    Nov 22, 2012
    Posts:
    836
    Hey everyone,

    Sorry I haven't poked my head in here for a bit. I'll try and respond to everything today. First things first though, I've finally got some good news for anyone who has been having ipv6 issues. It seems like the main issue (maybe the only issue?) is that the externalIPSource needs to be set to "ipv4.icanhazip.com" instead of "icanhazip.com." It looks like the problem was that icanhazip.com will return an ipv6 address if there is one but the plugin is specifically expecting an ipv4 address (if there is also an ipv6 address it is fetched separately from the externalIPv6Source).

    I'll put out an update correcting the default externalIPSource address but in the meantime anyone having issues should just be able to make the change themselves for an immediate fix.

    Thanks @deliinteractive for helping me figure out what was going wrong!
     
  46. thegreatzebadiah

    thegreatzebadiah

    Joined:
    Nov 22, 2012
    Posts:
    836
    It seems like something isn't being properly cleaned up. How are you disconnecting? NetworkManager.StopClient()? Also make sure that the instance of NetworkManager you call StopClient() on is cast as NATTraversal.NetworkManager and not Networking.NetworkManager.
     
  47. thegreatzebadiah

    thegreatzebadiah

    Joined:
    Nov 22, 2012
    Posts:
    836
    Thanks for pointing it out. I'll see if I can get it working properly in the next release. In the meantime on the client you can just check if each individual NetworkClient is active. So something like:

    bool isNetworkingActiveOnClient = directClient.active || punchthroughClient.active || relayClient.active

    You'll probably also need some null checks in there but that's the general idea.
     
  48. thegreatzebadiah

    thegreatzebadiah

    Joined:
    Nov 22, 2012
    Posts:
    836
    @omanak I responded to your direct message but I'm going to post the answer here as well for anyone else having similar issues:

    It's not enough to connect to the correct port on the server, you also must connect from the correct port on the client. That's what the clientPort is. Unfortunately Unity doesn't give you any way to set the port the client connects from when using a NetworkClient so it gets a bit tricky. In the plugin we do it using a bit of reflection so it looks something like this:
    Code (CSharp):
    1. FieldInfo clientIDField = typeof(NetworkClient).GetField("m_ClientId", BindingFlags.NonPublic | BindingFlags.Instance);
    2. // Start up a transport level host on the port that the hole was punched from
    3. int natListenSocketID = NetworkTransport.AddHost(topo, natListenPort);
    4. // Connect to the port on the server that we punched through to
    5. punchthroughClient.Connect(networkAddress, natConnectPort);
    6. // Remove the transport level host that the NetworkClient just created
    7. NetworkTransport.RemoveHost((int)clientIDField.GetValue(punchthroughClient));
    8. // Magic! Set the client's transport level host ID so that the client will use the host we started above
    9. // instead of the one it creates internally when we call Connect. This has to be done so that the connection
    10.  // will be made from the correct port, otherwise a random port is used to connect from and NAT Punchthrough
    11. // will fail.
    12. clientIDField.SetValue(punchthroughClient, natListenSocketID);
     
    Last edited: Feb 17, 2017
  49. thegreatzebadiah

    thegreatzebadiah

    Joined:
    Nov 22, 2012
    Posts:
    836
    Sorry to disappoint but I've never run into that particular error so I can't really offer any insight
     
  50. thegreatzebadiah

    thegreatzebadiah

    Joined:
    Nov 22, 2012
    Posts:
    836
    Well there's your problem right there. Punch-through is not going to work over a mobile network. This is the reason the plugin does not support mobile builds.

    This is fine. You are not required to use the NetworkManager, but you do lose out on a lot of functionality by not using it, like direct connections and automatically falling back to relay connections if punchthrough and direct connect fail. When making the punch-through connection in OnHolePunchedClient() just make sure you are starting a connection from the correct port on the client to the correct port on the server.

    You can not use a specific port for a punch-through connection. The ports are determined by the punch-through process.
     
    KaZe_ likes this.