Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice

What am I missing? Better solution to relay server / NAT Traversal

Discussion in 'Multiplayer' started by thegreatzebadiah, Nov 24, 2015.

  1. thegreatzebadiah

    thegreatzebadiah

    Joined:
    Nov 22, 2012
    Posts:
    836
    So my team is looking into the new UNet stuff. The relay server in particular seemed promising to us because it solves all those ugly NAT traversal problems. The one thing we really hate about it though is that in order for a client to send an rpc to all other clients the message has to go from client -> relay -> host -> relay(?) -> clients. I assume the same is true for state synchronization (NetworkTransform) as well.

    So after some time thinking about this what I'm wondering is why can't the relay server send out the client messages itself, why does it have to go through the host? Obviously something like client->relay->everyone is going to be faster. Is there some security concern?

    Which leads me to my real question: We've been toying around with the idea of writing something like a relay server for the old pre-UNet networking. Our plan is to host a build on a server that acts as the host for all games. All the build would do is send and receive RPC's and state synchronization, no physics, no graphics, it wouldn't have any of the scenes or assets or anything from the actual game.

    So this is where the sanity check comes in. It seems like this would solve all of our nat traversal problems with way less overhead than a dedicated server, and way less lag than something like the UNet relay servers, since the messages would just be going from client->host->clients with the host just being this dumb echo server thing. So...why isn't everyone doing this? What obvious thing are we missing that makes this impossible or a bad idea?
     
    Fuestrine likes this.
  2. seanr

    seanr

    Unity Technologies

    Joined:
    Sep 22, 2014
    Posts:
    669
    that is exactly what Photon Server is...
     
  3. thegreatzebadiah

    thegreatzebadiah

    Joined:
    Nov 22, 2012
    Posts:
    836
    Cool, that's good to hear. I suppose that means we're on the right track at least. We were looking into photon but we couldn't find any evidence that it has been successfully implemented in a project for the XBox One so we are a little wary of it. I'm not sure that implementing our own solution and dealing with scaling and load balancing ourselves is a great idea either though.

    Either way, thanks for the info, maybe we'll give Photon a closer look.
     
  4. SqueakyChickenStudios

    SqueakyChickenStudios

    Joined:
    Apr 21, 2014
    Posts:
    5
    To just touch on part of the question...

    The relay server cannot send out client messages itself because it's just a dumb relay (think of it like a proxy, it just forwards the data blindly).

    The relay server exists so that users can easily connect to a managed entry point and bypass any issues with nat/firewalls. The client itself is actually acting as a server in this case (controlling all game logic and managing the relevant packets to sync all users). The relay server exists so that the person hosting a match doesn't need to worry about their nat/firewall settings and the people joining that match don't need to know the IP address of the person they are connecting to. Both parties only connect to the relay server.
     
  5. thegreatzebadiah

    thegreatzebadiah

    Joined:
    Nov 22, 2012
    Posts:
    836
    Thanks pro4never, I understand how it's working pretty well (I think) I just don't really get the 'why'

    If I'm sending a client's state out to all the other clients I don't need it to pass through the 'server' client first, the server isn't doing anything to it other than sending it back out to all the other clients. I'm happy with a dumb relay that just forwards data, I'd just like it to be the tiniest bit smarter about where it forwards the data to.

    On a related side note:

    It drives me insane that in order to send an rpc from the owner of an object to all clients I now have to write two methods. One to send the [Command] from the owner to the server, and then another to send the [ClientRPC] from the server to all the other clients. This seems like a step backward from the old way where I could just send an RPC to whoever I want. Granted it was always passing through the server anyway, but I didn't have to write extra code for it. My Player class is littered with methods that look like:

    [Command]
    void CmdDoTheThing()
    {
    RPCDoTheThing();
    }

    Once again I have to wonder if I'm missing something.
     
    Last edited: May 7, 2016
  6. Zullar

    Zullar

    Joined:
    May 21, 2013
    Posts:
    650
    I agree having to create your own relay using [Command] and [ClientRpc] to bounce stuff through the server seems annoying, but I think it's intentional because it generates a level of security. No matter what is sent to the server, the server has the option to reject it and not send anything forward. Whereas without this step, the server would have no way to filter/secure any RPC's sent from one client to another. This is just a guess as to why they did it this way, but I'm not entirely sure.
     
  7. Bit Action

    Bit Action

    Joined:
    Dec 15, 2015
    Posts:
    1
    We developed a NAT traversal technology with better than 99% direct connections from the home, to mobile. We even traverse stacked NATs and commercial grade symmetric NATs. You can give it a try here: bitaction.com
     
  8. ObliviousHarmony

    ObliviousHarmony

    Joined:
    Jul 3, 2014
    Posts:
    79
    I believe, as Zullar stated, that the goal was security. UNet SCREAMS server-authoritative security, as it rightfully should. Commands are meant to be validated, and through them and SyncVars, the framework itself naturally encourages you to verify client information. The idea here is that there shouldn't ever be a situation where you simply replicate state from a client to all other clients. Instead, your goal should be to ensure that all clients have the current server state, and act on the server state accordingly. Supporting unsafe networking behaviour would simply make UNet look bad.

    Edit: Holy necro batman, what an advertisement!

    Edit2: I like that Unity offers a relay solution, but I wish that it was usable on our own hardware, and that it was a fallback after failed traversal attempts. As it stands, there's no easy way to develop our own relay (perhaps now that UNet is OSS? I haven't looked.)
     
    Last edited: Dec 15, 2015
  9. thegreatzebadiah

    thegreatzebadiah

    Joined:
    Nov 22, 2012
    Posts:
    836
    Amen to that. Connecting through the relay as it stands right now pretty much makes our game unplayable. I knew upgrading to UNET was going to take some effort but I didn't expect it to have such an impact on latency. I'm still hoping I'm either configuring something wrong or there just aren't enough relays yet or I can get something like bitaction working (which I'm looking into now).
     
  10. seanr

    seanr

    Unity Technologies

    Joined:
    Sep 22, 2014
    Posts:
    669
  11. thegreatzebadiah

    thegreatzebadiah

    Joined:
    Nov 22, 2012
    Posts:
    836
    @seanr thanks that turned out to be super relevant. AddExternalConnection has been really useful.

    @Bit Action I tried to sign up for an evaluation of your software but I just got some weird email back that said:
    this was back in december sometime. Sorry for resurrecting this post but I was just curious about your solution and if I could test it out somehow. Thanks!
     
  12. OlliQueck

    OlliQueck

    Joined:
    Apr 11, 2013
    Posts:
    49
    the client -> server -> client system imo is pretty intentional since you don't want clients to be able to control gameplay directly. I always think of it like this: Clients only give the input to the server, the server then tells everyone what that input has achieved. The thing i don't get is when i have established a connection, do i really still need that relaying? why is it not enough use the relay server to get a connection from clients to hosts and then let the them send their data directly?
     
  13. thegreatzebadiah

    thegreatzebadiah

    Joined:
    Nov 22, 2012
    Posts:
    836
    @Wurghi There's really no reason why Unity couldn't implement NAT Punch-through which would do what you want. They either haven't gotten around to it or they don't want to get around to it because they would rather have people paying for the relays. The relays alone are never going to let you send data directly though because they don't punch a hole through NAT, they just work around it by having players connect to the relays instead so no player has to deal with an incoming connection that they didn't first make an outgoing connection to.
     
  14. OlliQueck

    OlliQueck

    Joined:
    Apr 11, 2013
    Posts:
    49
    Okay but this means that to my usual ping of let's say 50 there adds another ping of the relay server which results in a much higher ping or wat? i can't imagine that this is a good thing for competitive games e.g.