Version: 2018.1
Network Level Loading (Legacy)
Construyendo los servidores de networking de unity por ti mismo (Legacy)

Master Server (Legacy)

(Para nuevos proyectos puedes usar el Nuevo Networking System introducido en 5.1. Esta información es para antiguos proyectos usando el sistema antiguo de networking.)

El Master Server es un lugar de encuentro que coloca unas instancias de juego en contacto con los clientes jugador que quiere conectarse a estas. También puede ocultar los números de puerto y las direcciones IP y realiza otras tareas técnicas que surgen cuando se configuran unas conexiones red, como el manejo de firewall y NAT punchthrough.

Cada instancia individual del juego que está ejecutándose proporciona un Game Type al Master Server. Cuando un jugador se conecta y consulta el Master Server por el Game Type con el que coincidan, el servidor responde con una lista de los juegos que se están ejecutando junto con la cantidad de jugares que tiene cada uno y si se necesita una contraseña para jugar. Las dos funciones utilizadas para intercambiar estos datos son MasterServer.RegisterHost() para el Servidor, y MasterServer.RequestHostList() para el cliente jugador.

Cuando llame RegisterHost, usted necesita pasar tres argumentos - gameTypeName (que es el Game Type mencionado anteriormente), gameName y comment - para el host (anfitrión) que se está registrando. RequestHostList toma como argumento el gameTypeName de los anfitriones con los que le interesa conectarse. Todos los registered hosts (anfitriones registradores) de ese tipo serán devueltos al cliente que los solicita. Esta es una operación asincrónica y la lista completa se puede recuperar con PollHostList() después de que haya llegado completa.

La tarea de NAT punchthrough del Master Server es en realidad realizada por un proceso separado llamado el Facilitator pero el Master Server de Unity corre ambos servicios en paralelo.

El Game Type es un nombre identificador que debería ser único para cada juego (aunque Unity no ofrece un sistema central de registro que garantice esto). Tiene sentido escoger un nombre distintivo que probablemente no sea utilizado por otra persona. Si hay varias versiones de su juego entonces podría advertirle al usuario que su cliente no es compatible con la versión ejecutándose en el servidor. La información de la versión se puede pasar en el campo de comentarios (esto en realidad son datos binarios por lo que la versión se puede pasar en cualquier formato deseado). El nombre del juego es simplemente el nombre de la instancia de juego en particular que es proporcionada por quién la esté configurando.

El campo de comentarios se puede utilizar de maneras más avanzadas si el Master Server en realidad es modificable (mirar la sección de Avanzado al final de la página para más información acerca de cómo hacer esto). Por ejemplo, podría reservar los primeros 10 bytes del campo de comentarios para una contraseña y luego extraer la contraseña en el Master Server cuando reciba la actualización de host. Puede rechazar la actualización de host si una revisión de contraseña falla.

Registrando un juego

Antes de registrar un juego, es importante habilitar o desactivar la funcionalidad NAT dependiendo si se soporta por el host (anfitrión); usted puede hacer esto con el parámetro useNat del Network.InitializeServer.

Un servidor podría empezar con código similar a este:-

using UnityEngine;
using UnityEngine.Network;
using System.Collections;

public class ExampleScript : MonoBehaviour {
    void OnGUI() {
        if (GUILayout.Button ("Start Server"))
        {
            // Use NAT punchthrough if no public IP present
            Network.InitializeServer(32, 25002, !Network.HavePublicAddress());
            MasterServer.RegisterHost("MyUniqueGameType", "JohnDoes game", "l33t game for all");
        }
    }
}

_Ejemplo de un C# script

function OnGUI() {
    if (GUILayout.Button ("Start Server"))
    {
        // Use NAT punchthrough if no public IP present
        Network.InitializeServer(32, 25002, !Network.HavePublicAddress());
        MasterServer.RegisterHost("MyUniqueGameType", "JohnDoes game", "l33t game for all");
    }
}

Ejemplo de un JS script

Aquí simplemente decidimos si NAT punchthrough se necesita revisando si o no la maquina tiene una dirección pública. Hay una función más sofisticada disponible llamada Network.TestConnection que puede decirle a usted si la maquina host puede hacer NAT o no. También hace pruebas de conectividad para direcciones IP publicas para ver si un firewall está bloqueando el puerto del juego. Las maquinas que tienen sus direcciones IP publicas siempre pasan la prueba NAT pero si la prueba falla entonces el host (anfitrión) no será capaz de conectarse a los clientes NAT. En tal caso, el usuario debe ser informado que el port forwarding debe estar habilitado para que el juego funcione. Las conexiones de bando de ancha domesticas usualmente tendrán direcciones NAT pero no será capaz de configurar un port forwarding (ya que no tienen una dirección IP pública persona). En estos casos, si la prueba NAT falla, el usuario debe ser informado que ejecutar un servidor no se recomienda ya que solamente los clientes en la misma red local se podrían conectar.

Si un host habilita la funcionalidad NAT si necesitarla entonces todavía será accesible. Sin embargo, los cliente que no puedan hacer NAT punchthrough podrían pensar incorrectamente que se pueden conectar a partir que el servidor tiene NAT habilitado.

Conectándose a un juego

Un objeto HostData se envia durante los registros del anfitrión o consultas. Contiene la siguiente información acerca de los hosts:-

boolean useNat Indica si el host (anfitrión) utiliza NAT punchthrough.
String gameType El game type (tipo de juego) del host (anfitrión).
String gameName El nombre del juego del host (anfitrión).
int connectedPlayers La cantidad de jugadores/clientes actualmente conectados.
int playerLimit La cantidad máxima de jugadores/clientes permitidos.
String[] IP La dirección IP interna del host (anfitrión). En un servidor con una dirección pública, las direcciones internas y externas son las mismas. Este campo se define como un arreglo ya que todas las direcciones IP asociadas con todas las interfaces activas de la maquina necesitan revisarse cuando se conecte internamente.
int port El puerto del host.
boolean passwordProtected Indica si tiene que proporcionar una contraseña para poderse conectar a este host (anfitrión).
String comment Cualquier comentario que fue hecho durante el registro del host (anfitrión).
String guid El network GUID del host (anfitrión). Esto se necesita para conectarse utilizando NAT punchthrough.

Esta información se puede utilizar por clientes para ver las capacidades de conexión de los hosts. Cuando NAT esté habilitado, usted necesita utilizar el GUID del host cuando se conecte. Esto se maneja automáticamente por usted cuando HostData se recupere a medida que se conecta. La rutina de conexión se podría ver algo así:

using UnityEngine;
using UnityEngine.Network;
using System.Collections;

public class ExampleScript : MonoBehaviour {
    void Awake() {
        MasterServer.RequestHostList("MadBubbleSmashGame");
    }
    
    void OnGUI() {
        HostData[] data = MasterServer.PollHostList();
        // Go through all the hosts in the host list
        foreach (var element in data)
        {
            GUILayout.BeginHorizontal();    
            var name = element.gameName + " " + element.connectedPlayers + " / " + element.playerLimit;
            GUILayout.Label(name);  
            GUILayout.Space(5);
            string hostInfo;
            hostInfo = "[";
            foreach (var host in element.ip)
                hostInfo = hostInfo + host + ":" + element.port + " ";
            hostInfo = hostInfo + "]";
            GUILayout.Label(hostInfo);  
            GUILayout.Space(5);
            GUILayout.Label(element.comment);
            GUILayout.Space(5);
            GUILayout.FlexibleSpace();
            if (GUILayout.Button("Connect"))
            {
                // Connect to HostData struct, internally the correct method is used (GUID when using NAT).
                Network.Connect(element);           
            }
            GUILayout.EndHorizontal();  
        }
    }
}

_Ejemplo de un C# script

function Awake() {
    MasterServer.RequestHostList("MadBubbleSmashGame");
}

function OnGUI() {
    var data : HostData[] = MasterServer.PollHostList();
    // Go through all the hosts in the host list
    for (var element in data)
    {
        GUILayout.BeginHorizontal();    
        var name = element.gameName + " " + element.connectedPlayers + " / " + element.playerLimit;
        GUILayout.Label(name);  
        GUILayout.Space(5);
        var hostInfo;
        hostInfo = "[";
        for (var host in element.ip)
            hostInfo = hostInfo + host + ":" + element.port + " ";
        hostInfo = hostInfo + "]";
        GUILayout.Label(hostInfo);  
        GUILayout.Space(5);
        GUILayout.Label(element.comment);
        GUILayout.Space(5);
        GUILayout.FlexibleSpace();
        if (GUILayout.Button("Connect"))
        {
            // Connect to HostData struct, internally the correct method is used (GUID when using NAT).
            Network.Connect(element);           
        }
        GUILayout.EndHorizontal();  
    }
}

Ejemplo de un JS script

Este ejemplo imprime toda la información del host (anfitrión) relevante por el Master Server. Otros datos útiles como la información ping o la ubicación de geográfica de los hosts (anfitriones) se puede agregar a esto.

NAT punchthrough

La disponibilidad de NAT punchthrough puede determinar si un computador en particular es adecuado para ser un servidor. Mientras algunos clientes se puedan conectar, puede que haya otros que tengan problemas para conectarse a un servidor NAT.

Por defecto, NAT punchthrough se proporciona con ayuda del Master Server pero no se necesita hacer de estar manera para el servicio NAT punchthrough. Si dos maquinas se conectan al Facilitator entonces parecerá como si ambos se conectarán mientras utilice el IP y puerto externo. El Master Server se utiliza para proporcionar esta información del puerto y la IP que de lo contrario sería difícil de determinar. Esto es porque el Master Server y el Facilitator tienen las mismas direcciones IP por defecto, para cambiar alguna utilice MasterServer.ipAddress, MasterServer.port, Network.natFacilitatorIP y Network.natFacilitatorPort

Avanzado

Unity Technologies también tiene un Master Server completamente desplegado disponible para propósitos de pruebas y este será el servidor que se utilizará por defecto. Sin embargo, el código fuente está abiertamente disponible para que cualquier utilice y el servidor se puede desplegar en Windows, Linux y Mac OS. Adicionalmente a construir el proyecto simplemente desde su fuente, puede haber casos dónde usted quiera modificar la manera en qué el Master Server maneja la información y cómo la comunica. Por ejemplo, podría optimizar el manejo de los datos host o limitar la cantidad de clientes que se devuelve en la lista host. Tales cambios requerirá modificaciones al código fuente; información acerca de cómo realizar esto se peude encontrar en Master Server Build page.

Network Level Loading (Legacy)
Construyendo los servidores de networking de unity por ti mismo (Legacy)