created centralized UDP Listener
This commit is contained in:
@ -1,6 +1,5 @@
|
||||
using System;
|
||||
using System.Net;
|
||||
using System.Net.Sockets;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Convai.Scripts.Runtime.LoggerSystem;
|
||||
@ -29,7 +28,6 @@ namespace Convai.Scripts.Runtime.Multiplayer
|
||||
public event Action<ConnectionState> OnConnectionStateChanged;
|
||||
|
||||
// Network components
|
||||
private UdpClient _udpClient;
|
||||
private bool _isRunning = false;
|
||||
private int _listenPort;
|
||||
private CancellationTokenSource _cancellationTokenSource;
|
||||
@ -134,19 +132,20 @@ namespace Convai.Scripts.Runtime.Multiplayer
|
||||
|
||||
try
|
||||
{
|
||||
// Create UDP client with port reuse for shared port
|
||||
_udpClient = new UdpClient();
|
||||
_udpClient.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
|
||||
_udpClient.Client.Bind(new IPEndPoint(IPAddress.Any, _listenPort));
|
||||
_udpClient.EnableBroadcast = true;
|
||||
// Wait for shared listener to be ready
|
||||
if (SharedUDPListener.Instance == null)
|
||||
{
|
||||
ConvaiLogger.Error("SharedUDPListener not found! Make sure it's in the scene.", ConvaiLogger.LogCategory.Character);
|
||||
return;
|
||||
}
|
||||
|
||||
// Subscribe to shared listener
|
||||
SharedUDPListener.Instance.OnPacketReceived += HandlePacketReceived;
|
||||
|
||||
_isRunning = true;
|
||||
SetConnectionState(ConnectionState.Discovering);
|
||||
|
||||
ConvaiLogger.Info($"🔍 Peer Discovery started - Player {localPlayerID} on port {_listenPort}", ConvaiLogger.LogCategory.Character);
|
||||
|
||||
// Start listening for discovery packets
|
||||
_ = ListenForDiscoveryPackets(_cancellationTokenSource.Token);
|
||||
ConvaiLogger.Info($"✅ Peer Discovery subscribed to shared listener - Player {localPlayerID}, listening for magic 0x{DISCOVERY_MAGIC:X}", ConvaiLogger.LogCategory.Character);
|
||||
|
||||
// Start broadcasting discovery requests
|
||||
_ = BroadcastDiscoveryRequests(_cancellationTokenSource.Token);
|
||||
@ -165,36 +164,27 @@ namespace Convai.Scripts.Runtime.Multiplayer
|
||||
if (!_isRunning) return;
|
||||
|
||||
_isRunning = false;
|
||||
_udpClient?.Close();
|
||||
_udpClient?.Dispose();
|
||||
_udpClient = null;
|
||||
|
||||
// Unsubscribe from shared listener
|
||||
if (SharedUDPListener.Instance != null)
|
||||
{
|
||||
SharedUDPListener.Instance.OnPacketReceived -= HandlePacketReceived;
|
||||
}
|
||||
|
||||
SetConnectionState(ConnectionState.Disconnected);
|
||||
ConvaiLogger.Info("Peer Discovery stopped", ConvaiLogger.LogCategory.Character);
|
||||
}
|
||||
|
||||
private async Task ListenForDiscoveryPackets(CancellationToken cancellationToken)
|
||||
private void HandlePacketReceived(byte[] data, IPEndPoint senderEndPoint)
|
||||
{
|
||||
while (_isRunning && !cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
try
|
||||
{
|
||||
var result = await _udpClient.ReceiveAsync();
|
||||
await ProcessDiscoveryPacket(result.Buffer, result.RemoteEndPoint);
|
||||
}
|
||||
catch (ObjectDisposedException)
|
||||
{
|
||||
// Normal when stopping
|
||||
break;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (_isRunning)
|
||||
{
|
||||
ConvaiLogger.Error($"Error receiving discovery packet: {ex.Message}", ConvaiLogger.LogCategory.Character);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Check if this is a discovery packet (by magic number)
|
||||
if (data.Length < 14) return;
|
||||
|
||||
uint magic = BitConverter.ToUInt32(data, 0);
|
||||
if (magic != DISCOVERY_MAGIC) return;
|
||||
|
||||
// Process discovery packet
|
||||
_ = ProcessDiscoveryPacket(data, senderEndPoint);
|
||||
}
|
||||
|
||||
private async Task BroadcastDiscoveryRequests(CancellationToken cancellationToken)
|
||||
@ -256,9 +246,8 @@ namespace Convai.Scripts.Runtime.Multiplayer
|
||||
{
|
||||
byte[] packet = CreateDiscoveryPacket(PACKET_TYPE_REQUEST);
|
||||
|
||||
// Broadcast to subnet (will be blocked by AP isolation but we try anyway)
|
||||
var broadcastEndPoint = new IPEndPoint(IPAddress.Broadcast, _listenPort);
|
||||
await _udpClient.SendAsync(packet, packet.Length, broadcastEndPoint);
|
||||
// Broadcast to subnet using shared listener
|
||||
await SharedUDPListener.Instance.SendBroadcastAsync(packet, _listenPort);
|
||||
|
||||
if (enableDebugLogging && UnityEngine.Random.value < 0.1f) // Log 10% of broadcasts to reduce spam
|
||||
{
|
||||
@ -276,7 +265,7 @@ namespace Convai.Scripts.Runtime.Multiplayer
|
||||
try
|
||||
{
|
||||
byte[] packet = CreateDiscoveryPacket(PACKET_TYPE_RESPONSE);
|
||||
await _udpClient.SendAsync(packet, packet.Length, targetEndPoint);
|
||||
await SharedUDPListener.Instance.SendAsync(packet, targetEndPoint);
|
||||
|
||||
if (enableDebugLogging)
|
||||
{
|
||||
@ -297,7 +286,7 @@ namespace Convai.Scripts.Runtime.Multiplayer
|
||||
|
||||
byte[] packet = CreateDiscoveryPacket(PACKET_TYPE_HEARTBEAT);
|
||||
var peerEndPoint = new IPEndPoint(IPAddress.Parse(_peerIP), _listenPort);
|
||||
await _udpClient.SendAsync(packet, packet.Length, peerEndPoint);
|
||||
await SharedUDPListener.Instance.SendAsync(packet, peerEndPoint);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user