예제 #1
0
        /// <summary>
        /// Connect client to a NetworkServer instance.
        /// </summary>
        /// <param name="address"></param>
        /// <param name="port"></param>
        public void Connect(string address = null, ushort?port = null)
        {
            ThrowIfActive();
            ThrowIfSocketIsMissing();

            _connectState = ConnectState.Connecting;

            World = new NetworkWorld();

            var endPoint = SocketFactory.GetConnectEndPoint(address, port);

            if (logger.LogEnabled())
            {
                logger.Log($"Client connecting to endpoint: {endPoint}");
            }

            var socket        = SocketFactory.CreateClientSocket();
            var maxPacketSize = SocketFactory.MaxPacketSize;

            MessageHandler = new MessageHandler(World, DisconnectOnException);
            var dataHandler = new DataHandler(MessageHandler);

            Metrics = EnablePeerMetrics ? new Metrics(MetricsSize) : null;

            var config = PeerConfig ?? new Config();

            NetworkWriterPool.Configure(maxPacketSize);

            _peer                     = new Peer(socket, maxPacketSize, dataHandler, config, LogFactory.GetLogger <Peer>(), Metrics);
            _peer.OnConnected        += Peer_OnConnected;
            _peer.OnConnectionFailed += Peer_OnConnectionFailed;
            _peer.OnDisconnected     += Peer_OnDisconnected;

            var connection = _peer.Connect(endPoint);

            if (RunInBackground)
            {
                Application.runInBackground = RunInBackground;
            }

            // setup all the handlers
            Player = new NetworkPlayer(connection);
            dataHandler.SetConnection(connection, Player);

            RegisterMessageHandlers();
            InitializeAuthEvents();
            // invoke started event after everything is set up, but before peer has connected
            _started.Invoke();
        }
예제 #2
0
        void Initialize()
        {
            if (initialized)
            {
                return;
            }

            initialized = true;
            World       = new NetworkWorld();

            Application.quitting += Stop;
            if (logger.LogEnabled())
            {
                logger.Log($"NetworkServer Created, Mirage version: {Version.Current}");
            }


            //Make sure connections are cleared in case any old connections references exist from previous sessions
            Players.Clear();

            if (Transport is null)
            {
                Transport = GetComponent <Transport>();
            }
            if (Transport == null)
            {
                throw new InvalidOperationException("Transport could not be found for NetworkServer");
            }

            if (authenticator != null)
            {
                authenticator.OnServerAuthenticated += OnAuthenticated;

                Connected.AddListener(authenticator.OnServerAuthenticateInternal);
            }
            else
            {
                // if no authenticator, consider every connection as authenticated
                Connected.AddListener(OnAuthenticated);
            }
        }
예제 #3
0
        /// <summary>
        /// Connect client to a NetworkServer instance.
        /// </summary>
        /// <param name="uri">Address of the server to connect to</param>
        public async UniTask ConnectAsync(Uri uri)
        {
            if (logger.LogEnabled())
            {
                logger.Log("Client Connect: " + uri);
            }

            if (Transport == null)
            {
                Transport = GetComponent <Transport>();
            }
            if (Transport == null)
            {
                throw new InvalidOperationException("Transport could not be found for NetworkClient");
            }

            connectState = ConnectState.Connecting;

            try
            {
                IConnection transportConnection = await Transport.ConnectAsync(uri);

                World = new NetworkWorld();
                InitializeAuthEvents();

                // setup all the handlers
                Player = new NetworkPlayer(transportConnection);
                Time.Reset();

                RegisterMessageHandlers();
                Time.UpdateClient(this);
                OnConnected().Forget();
            }
            catch (Exception)
            {
                connectState = ConnectState.Disconnected;
                throw;
            }
        }
예제 #4
0
        /// <summary>
        /// Start the server
        /// <para>If <paramref name="localClient"/> is given then will start in host mode</para>
        /// </summary>
        /// <param name="config">Config for <see cref="Peer"/></param>
        /// <param name="localClient">if not null then start the server and client in hostmode</param>
        // Has to be called "StartServer" to stop unity complaining about "Start" method
        public void StartServer(NetworkClient localClient = null)
        {
            ThrowIfActive();
            ThrowIfSocketIsMissing();

            Application.quitting += Stop;
            if (logger.LogEnabled())
            {
                logger.Log($"NetworkServer Created, Mirage version: {Version.Current}");
            }

            logger.Assert(Players.Count == 0, "Player should have been reset since previous session");
            logger.Assert(connections.Count == 0, "Connections should have been reset since previous session");

            World         = new NetworkWorld();
            SyncVarSender = new SyncVarSender();

            LocalClient    = localClient;
            MessageHandler = new MessageHandler(World, DisconnectOnException);
            MessageHandler.RegisterHandler <NetworkPingMessage>(World.Time.OnServerPing);

            ISocket socket      = SocketFactory.CreateServerSocket();
            var     dataHandler = new DataHandler(MessageHandler, connections);

            Metrics = EnablePeerMetrics ? new Metrics(MetricsSize) : null;

            Config config = PeerConfig;

            if (config == null)
            {
                config = new Config
                {
                    // only use MaxConnections if config was null
                    MaxConnections = MaxConnections,
                };
            }

            NetworkWriterPool.Configure(config.MaxPacketSize);

            // Only create peer if listening
            if (Listening)
            {
                peer                 = new Peer(socket, dataHandler, config, LogFactory.GetLogger <Peer>(), Metrics);
                peer.OnConnected    += Peer_OnConnected;
                peer.OnDisconnected += Peer_OnDisconnected;

                peer.Bind(SocketFactory.GetBindEndPoint());
            }

            if (logger.LogEnabled())
            {
                logger.Log("Server started listening");
            }

            InitializeAuthEvents();
            Active = true;
            _started?.Invoke();

            if (LocalClient != null)
            {
                // we should call onStartHost after transport is ready to be used
                // this allows server methods like NetworkServer.Spawn to be called in there
                _onStartHost?.Invoke();

                localClient.ConnectHost(this, dataHandler);
                if (logger.LogEnabled())
                {
                    logger.Log("NetworkServer StartHost");
                }
            }
        }
예제 #5
0
        /// <summary>
        /// Start the server
        /// <para>If <paramref name="localClient"/> is given then will start in host mode</para>
        /// </summary>
        /// <param name="config">Config for <see cref="Peer"/></param>
        /// <param name="localClient">if not null then start the server and client in hostmode</param>
        // Has to be called "StartServer" to stop unity complaining about "Start" method
        public void StartServer(NetworkClient localClient = null)
        {
            ThrowIfActive();
            ThrowIfSocketIsMissing();

            Application.quitting += Stop;
            if (logger.LogEnabled())
            {
                logger.Log($"NetworkServer created, Mirage version: {Version.Current}");
            }

            logger.Assert(Players.Count == 0, "Player should have been reset since previous session");
            logger.Assert(_connections.Count == 0, "Connections should have been reset since previous session");

            World         = new NetworkWorld();
            SyncVarSender = new SyncVarSender();

            LocalClient    = localClient;
            MessageHandler = new MessageHandler(World, DisconnectOnException);
            MessageHandler.RegisterHandler <NetworkPingMessage>(World.Time.OnServerPing);

            var dataHandler = new DataHandler(MessageHandler, _connections);

            Metrics = EnablePeerMetrics ? new Metrics(MetricsSize) : null;

            var config = PeerConfig;

            if (config == null)
            {
                config = new Config
                {
                    // only use MaxConnections if config was null
                    MaxConnections = MaxConnections,
                };
            }

            var maxPacketSize = SocketFactory.MaxPacketSize;

            NetworkWriterPool.Configure(maxPacketSize);

            // Are we listening for incoming connections?
            // If yes, set up a socket for incoming connections (we're a multiplayer game).
            // If not, that's okay. Some games use a non-listening server for their single player game mode (Battlefield, Call of Duty...)
            if (Listening)
            {
                // Create a server specific socket.
                var socket = SocketFactory.CreateServerSocket();

                // Tell the peer to use that newly created socket.
                _peer                 = new Peer(socket, maxPacketSize, dataHandler, config, LogFactory.GetLogger <Peer>(), Metrics);
                _peer.OnConnected    += Peer_OnConnected;
                _peer.OnDisconnected += Peer_OnDisconnected;
                // Bind it to the endpoint.
                _peer.Bind(SocketFactory.GetBindEndPoint());

                if (logger.LogEnabled())
                {
                    logger.Log($"Server started, listening for connections. Using socket {socket.GetType()}");
                }

                if (RunInBackground)
                {
                    Application.runInBackground = RunInBackground;
                }
            }
            else
            {
                // Nicely mention that we're going live, but not listening for connections.
                if (logger.LogEnabled())
                {
                    logger.Log("Server started, but not listening for connections: Attempts to connect to this instance will fail!");
                }
            }

            InitializeAuthEvents();
            Active = true;
            _started?.Invoke();

            if (LocalClient != null)
            {
                // we should call onStartHost after transport is ready to be used
                // this allows server methods like NetworkServer.Spawn to be called in there
                _onStartHost?.Invoke();

                localClient.ConnectHost(this, dataHandler);
                if (logger.LogEnabled())
                {
                    logger.Log("NetworkServer StartHost");
                }
            }
        }