78 lines
2.5 KiB
C#
78 lines
2.5 KiB
C#
#nullable enable
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using Cysharp.Threading.Tasks;
|
|
|
|
namespace ShrinkNetwork
|
|
{
|
|
public sealed class ShrinkLoopbackTransport : IShrinkNetworkAsyncTransport, IShrinkNetworkSessionControlTransport
|
|
{
|
|
private readonly HashSet<long> _openedSessions = new();
|
|
private ShrinkLoopbackTransport? _peer;
|
|
|
|
public bool IsStarted { get; private set; }
|
|
|
|
public event Action<ShrinkNetworkTransportEvent>? OnEvent;
|
|
|
|
public void LinkPeer(ShrinkLoopbackTransport peer)
|
|
{
|
|
_peer = peer;
|
|
if (peer._peer != this)
|
|
peer.LinkPeer(this);
|
|
}
|
|
|
|
public void Start()
|
|
{
|
|
IsStarted = true;
|
|
}
|
|
|
|
public void Stop()
|
|
{
|
|
IsStarted = false;
|
|
}
|
|
|
|
public void OpenSession(long sessionId, string remoteAddress = "loopback")
|
|
{
|
|
_openedSessions.Add(sessionId);
|
|
_peer?._openedSessions.Add(sessionId);
|
|
OnEvent?.Invoke(ShrinkNetworkTransportEvent.Connected(sessionId, remoteAddress));
|
|
_peer?.OnEvent?.Invoke(ShrinkNetworkTransportEvent.Connected(sessionId, remoteAddress));
|
|
}
|
|
|
|
public void CloseSession(long sessionId, string remoteAddress = "loopback")
|
|
{
|
|
_openedSessions.Remove(sessionId);
|
|
_peer?._openedSessions.Remove(sessionId);
|
|
OnEvent?.Invoke(ShrinkNetworkTransportEvent.Disconnected(sessionId, remoteAddress));
|
|
_peer?.OnEvent?.Invoke(ShrinkNetworkTransportEvent.Disconnected(sessionId, remoteAddress));
|
|
}
|
|
|
|
public bool DisconnectSession(long sessionId, string? reason = null)
|
|
{
|
|
if (!_openedSessions.Contains(sessionId))
|
|
return false;
|
|
|
|
CloseSession(sessionId);
|
|
return true;
|
|
}
|
|
|
|
public void Send(long sessionId, byte[] packetData)
|
|
{
|
|
SendAsync(sessionId, packetData).Forget();
|
|
}
|
|
|
|
public UniTask SendAsync(long sessionId, byte[] packetData)
|
|
{
|
|
if (!IsStarted)
|
|
throw new InvalidOperationException("Transport has not been started.");
|
|
if (_peer == null)
|
|
throw new InvalidOperationException("Peer transport is not linked.");
|
|
if (!_openedSessions.Contains(sessionId))
|
|
throw new InvalidOperationException($"Session {sessionId} is not open.");
|
|
|
|
_peer.OnEvent?.Invoke(ShrinkNetworkTransportEvent.Packet(sessionId, packetData));
|
|
return UniTask.CompletedTask;
|
|
}
|
|
}
|
|
}
|