/// <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(); }
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); } }
/// <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; } }
/// <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"); } } }
/// <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"); } } }