using System; using UnityEngine; using UnityEngine.Events; namespace Mirror { // UnityEvent definitions [Serializable] public class ClientDataReceivedEvent : UnityEvent, int> { } [Serializable] public class UnityEventException : UnityEvent { } [Serializable] public class UnityEventInt : UnityEvent { } [Serializable] public class ServerDataReceivedEvent : UnityEvent, int> { } [Serializable] public class UnityEventIntException : UnityEvent { } /// /// Abstract transport layer component /// /// /// note: Not all transports need a port, so add it to yours if needed. /// public abstract class Transport : MonoBehaviour { /// /// The current transport used by Mirror. /// public static Transport activeTransport; /// /// Is this transport available in the current platform? /// Some transports might only be available in mobile /// Many will not work in webgl /// Example usage: return Application.platform == RuntimePlatform.WebGLPlayer /// /// True if this transport works in the current platform public abstract bool Available(); #region Client /// /// Notify subscribers when when this client establish a successful connection to the server /// [HideInInspector] public UnityEvent OnClientConnected = new UnityEvent(); /// /// Notify subscribers when this client receive data from the server /// // Note: we provide channelId for NetworkDiagnostics. [HideInInspector] public ClientDataReceivedEvent OnClientDataReceived = new ClientDataReceivedEvent(); /// /// Notify subscribers when this client encounters an error communicating with the server /// [HideInInspector] public UnityEventException OnClientError = new UnityEventException(); /// /// Notify subscribers when this client disconnects from the server /// [HideInInspector] public UnityEvent OnClientDisconnected = new UnityEvent(); /// /// Determines if we are currently connected to the server /// /// True if a connection has been established to the server public abstract bool ClientConnected(); /// /// Establish a connection to a server /// /// The IP address or FQDN of the server we are trying to connect to public abstract void ClientConnect(string address); /// /// Establish a connection to a server /// /// The address of the server we are trying to connect to public virtual void ClientConnect(Uri uri) { // By default, to keep backwards compatibility, just connect to the host // in the uri ClientConnect(uri.Host); } /// /// Send data to the server /// /// The channel to use. 0 is the default channel, /// but some transports might want to provide unreliable, encrypted, compressed, or any other feature /// as new channels /// The data to send to the server. Will be recycled after returning, so either use it directly or copy it internally. This allows for allocation-free sends! public abstract void ClientSend(int channelId, ArraySegment segment); /// /// Disconnect this client from the server /// public abstract void ClientDisconnect(); #endregion #region Server /// /// Retrieves the address of this server. /// Useful for network discovery /// /// the url at which this server can be reached public abstract Uri ServerUri(); /// /// Notify subscribers when a client connects to this server /// [HideInInspector] public UnityEventInt OnServerConnected = new UnityEventInt(); /// /// Notify subscribers when this server receives data from the client /// // Note: we provide channelId for NetworkDiagnostics. [HideInInspector] public ServerDataReceivedEvent OnServerDataReceived = new ServerDataReceivedEvent(); /// /// Notify subscribers when this server has some problem communicating with the client /// [HideInInspector] public UnityEventIntException OnServerError = new UnityEventIntException(); /// /// Notify subscribers when a client disconnects from this server /// [HideInInspector] public UnityEventInt OnServerDisconnected = new UnityEventInt(); /// /// Determines if the server is up and running /// /// true if the transport is ready for connections from clients public abstract bool ServerActive(); /// /// Start listening for clients /// public abstract void ServerStart(); /// /// Send data to a client. /// /// The client connection id to send the data to /// The channel to be used. Transports can use channels to implement /// other features such as unreliable, encryption, compression, etc... /// public abstract void ServerSend(int connectionId, int channelId, ArraySegment segment); /// /// Disconnect a client from this server. Useful to kick people out. /// /// the id of the client to disconnect /// true if the client was kicked public abstract bool ServerDisconnect(int connectionId); /// /// Get the client address /// /// id of the client /// address of the client public abstract string ServerGetClientAddress(int connectionId); /// /// Stop listening for clients and disconnect all existing clients /// public abstract void ServerStop(); #endregion /// /// The maximum packet size for a given channel. Unreliable transports /// usually can only deliver small packets. Reliable fragmented channels /// can usually deliver large ones. /// /// GetMaxPacketSize needs to return a value at all times. Even if the /// Transport isn't running, or isn't Available(). This is because /// Fallback and Multiplex transports need to find the smallest possible /// packet size at runtime. /// /// channel id /// the size in bytes that can be sent via the provided channel public abstract int GetMaxPacketSize(int channelId = Channels.DefaultReliable); /// /// Shut down the transport, both as client and server /// public abstract void Shutdown(); // block Update() to force Transports to use LateUpdate to avoid race // conditions. messages should be processed after all the game state // was processed in Update. // -> in other words: use LateUpdate! // -> uMMORPG 480 CCU stress test: when bot machine stops, it causes // 'Observer not ready for ...' log messages when using Update // -> occupying a public Update() function will cause Warnings if a // transport uses Update. // // IMPORTANT: set script execution order to >1000 to call Transport's // LateUpdate after all others. Fixes race condition where // e.g. in uSurvival Transport would apply Cmds before // ShoulderRotation.LateUpdate, resulting in projectile // spawns at the point before shoulder rotation. #pragma warning disable UNT0001 // Empty Unity message public void Update() { } #pragma warning restore UNT0001 // Empty Unity message /// /// called when quitting the application by closing the window / pressing stop in the editor /// virtual so that inheriting classes' OnApplicationQuit() can call base.OnApplicationQuit() too /// public virtual void OnApplicationQuit() { // stop transport (e.g. to shut down threads) // (when pressing Stop in the Editor, Unity keeps threads alive // until we press Start again. so if Transports use threads, we // really want them to end now and not after next start) Shutdown(); } } }