mirror of
https://github.com/MirrorNetworking/Mirror.git
synced 2024-11-18 02:50:32 +00:00
Add multiplex transport (#358)
* Add multiplex transport * Simplify Availability method * Update MultiplexTransport.cs
This commit is contained in:
parent
bb749e7325
commit
fba7b3f826
@ -174,6 +174,12 @@ public override void ClientDisconnect()
|
||||
}
|
||||
}
|
||||
|
||||
public override bool Available()
|
||||
{
|
||||
// websocket is available in all platforms (including webgl)
|
||||
return useWebsockets || base.Available();
|
||||
}
|
||||
|
||||
// server //////////////////////////////////////////////////////////////
|
||||
public override bool ServerActive()
|
||||
{
|
||||
|
191
Assets/Mirror/Runtime/Transport/MultiplexTransport.cs
Normal file
191
Assets/Mirror/Runtime/Transport/MultiplexTransport.cs
Normal file
@ -0,0 +1,191 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Mirror
|
||||
{
|
||||
// a transport that can listen to multiple underlying transport at the same time
|
||||
public class MultiplexTransport : Transport
|
||||
{
|
||||
public Transport[] transports;
|
||||
|
||||
public void Awake()
|
||||
{
|
||||
if (transports == null || transports.Length == 0)
|
||||
{
|
||||
Debug.LogError("Multiplex transport requires at least 1 underlying transport");
|
||||
}
|
||||
InitClient();
|
||||
InitServer();
|
||||
}
|
||||
|
||||
#region Client
|
||||
// clients always pick the first transport
|
||||
void InitClient()
|
||||
{
|
||||
// wire all the base transports to my events
|
||||
foreach (Transport transport in transports)
|
||||
{
|
||||
transport.OnClientConnected.AddListener(OnClientConnected.Invoke );
|
||||
transport.OnClientDataReceived.AddListener(OnClientDataReceived.Invoke);
|
||||
transport.OnClientError.AddListener(OnClientError.Invoke );
|
||||
transport.OnClientDisconnected.AddListener(OnClientDisconnected.Invoke);
|
||||
}
|
||||
}
|
||||
|
||||
// The client just uses the first transport available
|
||||
Transport getAvailableTransport()
|
||||
{
|
||||
foreach (Transport transport in transports)
|
||||
{
|
||||
if (transport.Available())
|
||||
{
|
||||
return transport;
|
||||
}
|
||||
}
|
||||
throw new Exception("No transport suitable for this platform");
|
||||
}
|
||||
|
||||
public override void ClientConnect(string address)
|
||||
{
|
||||
getAvailableTransport().ClientConnect(address);
|
||||
}
|
||||
|
||||
public override bool ClientConnected()
|
||||
{
|
||||
return getAvailableTransport().ClientConnected();
|
||||
}
|
||||
|
||||
public override void ClientDisconnect()
|
||||
{
|
||||
getAvailableTransport().ClientDisconnect();
|
||||
}
|
||||
|
||||
public override bool ClientSend(int channelId, byte[] data)
|
||||
{
|
||||
return getAvailableTransport().ClientSend(channelId, data);
|
||||
}
|
||||
|
||||
public override int GetMaxPacketSize(int channelId = 0)
|
||||
{
|
||||
return getAvailableTransport().GetMaxPacketSize(channelId);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
#region Server
|
||||
// connection ids get mapped to base transports
|
||||
// if we have 3 transports, then
|
||||
// transport 0 will produce connection ids [0, 3, 6, 9, ...]
|
||||
// transport 1 will produce connection ids [1, 4, 7, 10, ...]
|
||||
// transport 2 will produce connection ids [2, 5, 8, 11, ...]
|
||||
int FromBaseId(int transportId, int connectionId)
|
||||
{
|
||||
return connectionId * transports.Length + transportId;
|
||||
}
|
||||
|
||||
int ToBaseId(int connectionId)
|
||||
{
|
||||
return connectionId / transports.Length;
|
||||
}
|
||||
|
||||
int ToTransportId(int connectionId)
|
||||
{
|
||||
return connectionId % transports.Length;
|
||||
}
|
||||
|
||||
void InitServer()
|
||||
{
|
||||
// wire all the base transports to my events
|
||||
for (int i = 0; i < transports.Length; i++)
|
||||
{
|
||||
// this is required for the handlers, if I use i directly
|
||||
// then all the handlers will use the last i
|
||||
int locali = i;
|
||||
Transport transport = transports[i];
|
||||
|
||||
transport.OnServerConnected.AddListener(baseConnectionId =>
|
||||
{
|
||||
OnServerConnected.Invoke(FromBaseId(locali, baseConnectionId));
|
||||
});
|
||||
|
||||
transport.OnServerDataReceived.AddListener((baseConnectionId, data) =>
|
||||
{
|
||||
OnServerDataReceived.Invoke(FromBaseId(locali, baseConnectionId), data);
|
||||
});
|
||||
|
||||
transport.OnServerError.AddListener((baseConnectionId, error) =>
|
||||
{
|
||||
OnServerError.Invoke(FromBaseId(locali, baseConnectionId), error);
|
||||
});
|
||||
transport.OnServerDisconnected.AddListener(baseConnectionId =>
|
||||
{
|
||||
OnServerDisconnected.Invoke(FromBaseId(locali, baseConnectionId));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public override bool ServerActive()
|
||||
{
|
||||
return transports.All(t => t.ServerActive());
|
||||
}
|
||||
|
||||
public override bool GetConnectionInfo(int connectionId, out string address)
|
||||
{
|
||||
int baseConnectionId = ToBaseId(connectionId);
|
||||
int transportId = ToTransportId(connectionId);
|
||||
return transports[transportId].GetConnectionInfo(baseConnectionId, out address);
|
||||
}
|
||||
|
||||
public override bool ServerDisconnect(int connectionId)
|
||||
{
|
||||
int baseConnectionId = ToBaseId(connectionId);
|
||||
int transportId = ToTransportId(connectionId);
|
||||
return transports[transportId].ServerDisconnect(baseConnectionId);
|
||||
}
|
||||
|
||||
public override bool ServerSend(int connectionId, int channelId, byte[] data)
|
||||
{
|
||||
int baseConnectionId = ToBaseId(connectionId);
|
||||
int transportId = ToTransportId(connectionId);
|
||||
return transports[transportId].ServerSend(baseConnectionId, channelId, data);
|
||||
}
|
||||
|
||||
public override void ServerStart()
|
||||
{
|
||||
foreach (Transport transport in transports)
|
||||
{
|
||||
transport.ServerStart();
|
||||
}
|
||||
}
|
||||
|
||||
public override void ServerStop()
|
||||
{
|
||||
foreach (Transport transport in transports)
|
||||
{
|
||||
transport.ServerStop();
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
public override void Shutdown()
|
||||
{
|
||||
foreach (Transport transport in transports)
|
||||
{
|
||||
transport.Shutdown();
|
||||
}
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
StringBuilder builder = new StringBuilder();
|
||||
foreach (Transport transport in transports)
|
||||
{
|
||||
builder.AppendLine(transport.ToString());
|
||||
}
|
||||
return builder.ToString().Trim();
|
||||
}
|
||||
}
|
||||
}
|
11
Assets/Mirror/Runtime/Transport/MultiplexTransport.cs.meta
Normal file
11
Assets/Mirror/Runtime/Transport/MultiplexTransport.cs.meta
Normal file
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 929e3234c7db540b899f00183fc2b1fe
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -26,10 +26,20 @@ public abstract class Transport : MonoBehaviour
|
||||
public abstract bool ClientSend(int channelId, byte[] data);
|
||||
public abstract void ClientDisconnect();
|
||||
|
||||
// determines if the transport is available for this platform
|
||||
// by default a transport is available in all platforms except webgl
|
||||
public virtual bool Available()
|
||||
{
|
||||
return Application.platform != RuntimePlatform.WebGLPlayer;
|
||||
}
|
||||
|
||||
|
||||
// server
|
||||
[HideInInspector] public UnityEventInt OnServerConnected;
|
||||
[HideInInspector] public UnityEventIntByteArray OnServerDataReceived;
|
||||
[HideInInspector] public UnityEventIntException OnServerError;
|
||||
|
||||
|
||||
[HideInInspector] public UnityEventInt OnServerDisconnected;
|
||||
|
||||
public abstract bool ServerActive();
|
||||
|
Loading…
Reference in New Issue
Block a user