骑行界面调整,底层逻辑细化
This commit is contained in:
1 parent
d5133ee7b0
commit
9a7830f46a
168 files changed
+19164
-393
No files matched your search
@@ -0,0 +1,18 @@
|
||||
using Assets.Scenes.Ride.Scripts.Model;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Assets.Scenes.Ride.Scripts.Network
|
||||
{
|
||||
interface IService
|
||||
{
|
||||
void Start(Action<List<ReceiveMsgModel>> action);
|
||||
|
||||
void Send(byte[] dgram, int bytes);
|
||||
|
||||
void Close();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 04b976b21b69ff640956ca0574491797
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,367 @@
|
||||
using Assets.Scenes.Ride.Scripts.Model;
|
||||
using Assets.Scenes.Ride.Scripts.Network;
|
||||
using Assets.Scripts;
|
||||
using Assets.Scripts.Apis;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Assets.Scenes.Ride.Scripts
|
||||
{
|
||||
public class MapUDPService
|
||||
{
|
||||
private static IService _udpService;
|
||||
//private static UdpClient udpClient;
|
||||
//private static IPEndPoint iPEndPoint;
|
||||
private static bool isExit = false;
|
||||
//private static Task task = null;
|
||||
//private static CancellationTokenSource cts { get; set; }
|
||||
private static CancellationToken ct { get; set; }
|
||||
//private static List<OnlineUser> onlineUsers { get; set; } = new List<OnlineUser>();
|
||||
private static System.Timers.Timer heartbeat { get; set; }
|
||||
public static bool Pause { get; set; } = false;
|
||||
|
||||
private static OnlineUserHelper _onlineUserHelper;
|
||||
private static OnlineUserHelper onlineUserHelper
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_onlineUserHelper == null)
|
||||
{
|
||||
_onlineUserHelper = new OnlineUserHelper();
|
||||
}
|
||||
return _onlineUserHelper;
|
||||
}
|
||||
}
|
||||
private static DateTime LastActiveTime = DateTime.Now;
|
||||
private static List<ReceiveMsgModel> msgs = new List<ReceiveMsgModel>();
|
||||
/// <summary>
|
||||
/// 初始化(如果UDP服务未启动,则会已没5秒一次不断尝试,直到连接上为止,前端不需要考虑任何UDP连接的事情)
|
||||
/// </summary>
|
||||
public static void Init()
|
||||
{
|
||||
try
|
||||
{
|
||||
//var ddd = new MapWorkoutService().GetRealOnlineUserInfo(new List<int> { 6 });
|
||||
isExit = false;
|
||||
Pause = false;
|
||||
|
||||
if (_udpService == null)
|
||||
{
|
||||
_udpService = new TcpService1();
|
||||
|
||||
_udpService.Start(list =>
|
||||
{
|
||||
LastActiveTime = DateTime.Now;
|
||||
//onlineUserHelper.RemoveExceptionData(list);
|
||||
msgs = list;
|
||||
onlineUserHelper.SetOnlineUser(msgs);
|
||||
});
|
||||
|
||||
heartbeat = new System.Timers.Timer();
|
||||
heartbeat.Interval = 1000;
|
||||
heartbeat.AutoReset = true;
|
||||
heartbeat.Enabled = true;
|
||||
heartbeat.Elapsed += Heartbeat_Elapsed;
|
||||
}
|
||||
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Trace.WriteLine("UDP:" + e.Message);
|
||||
}
|
||||
finally
|
||||
{
|
||||
//发送一条心跳包
|
||||
//SendHeartbeat();
|
||||
}
|
||||
}
|
||||
|
||||
private static void Heartbeat_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
|
||||
{
|
||||
var now = DateTime.Now;
|
||||
//超过一秒没有收到消息
|
||||
if ((now - LastActiveTime).TotalSeconds > 1)
|
||||
{
|
||||
onlineUserHelper.SetOnlineUser(new List<ReceiveMsgModel>());
|
||||
}
|
||||
if (now.Second % 20 == 0)
|
||||
{
|
||||
//LastActiveTime = now;
|
||||
SendHeartbeat();
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// 发送心跳包
|
||||
/// </summary>
|
||||
private static void SendHeartbeat()
|
||||
{
|
||||
Send(0, PubCommData.CurrentUser.Id, new double[] { 0, 0 }, false, false, 0, true, 0);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 发送数据
|
||||
/// </summary>
|
||||
/// <param name="RouteId">路书Id</param>
|
||||
/// <param name="MemberId">用户id</param>
|
||||
/// <param name="Point">当前点位</param>
|
||||
/// <param name="prop">属性</param>
|
||||
/// <param name="IsCompleted">是否完成</param>
|
||||
/// <param name="exit">是否退出</param>
|
||||
public static void Send(int RouteId, int MemberId, double[] Point, bool IsCompleted = false, bool exit = false,
|
||||
double endDistance = 0, bool showVirtual = false, byte commandType = 1, double speed = 0, bool isVirtual = false, double preDistance = 0,
|
||||
double weightKg = 0, int competitionId = 0, bool saved = false)
|
||||
{
|
||||
try
|
||||
{
|
||||
var model = new MsgModel
|
||||
{
|
||||
RouteId = RouteId,
|
||||
MemberId = MemberId,
|
||||
Point = Point,
|
||||
IsCompleted = IsCompleted,
|
||||
exit = exit,
|
||||
EndDistance = endDistance,
|
||||
//ShowVirtual = showVirtual,
|
||||
CommandType = commandType,
|
||||
Speed = speed,
|
||||
//IsVirtual = isVirtual,
|
||||
PreDistance = preDistance,
|
||||
WeightKg = weightKg,
|
||||
Competitionid = competitionId,
|
||||
Saved = saved,
|
||||
V = 1
|
||||
};
|
||||
var sendBytes = Encoding.UTF8.GetBytes(Newtonsoft.Json.JsonConvert.SerializeObject(model));
|
||||
_udpService.Send(sendBytes, sendBytes.Length);
|
||||
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Console.WriteLine("发送失败:" + e);
|
||||
}
|
||||
}
|
||||
|
||||
public static void Dispose()
|
||||
{
|
||||
try
|
||||
{
|
||||
isExit = true;
|
||||
if (MapUDPService._udpService == null) return;
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
Send(0, PubCommData.CurrentUser.Id, new double[] { 1, 1 }, true, isExit);
|
||||
}
|
||||
_udpService.Close();
|
||||
|
||||
//task.Dispose();
|
||||
_udpService = null;
|
||||
_onlineUserHelper = null;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
}
|
||||
finally
|
||||
{
|
||||
//停止计时
|
||||
if (heartbeat != null)
|
||||
{
|
||||
heartbeat.Stop();
|
||||
heartbeat.Close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static OnlineUser GetOnlineUserLastDataById(int userId)
|
||||
{
|
||||
//return _onlineUserHelper.GetOnlineUserLastDataById(userId);
|
||||
//var msg = msgs.Where(m => m.MemberId == userId);
|
||||
//if (msg == null) return null;
|
||||
return onlineUserHelper.OnlineUsers.FirstOrDefault(u => u.Id == userId);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 根据路书获取在线用户
|
||||
/// </summary>
|
||||
/// <param name="routeId"></param>
|
||||
/// <returns></returns>
|
||||
public static List<OnlineUser> GetOnlineUsers(params int[] routeId)
|
||||
{
|
||||
//return onlineUsers.Where(n => routeId.Contains(n.RouteId)).ToList();
|
||||
var result = onlineUserHelper.OnlineUsers.Where(u => routeId.Contains(u.RouteId)).ToList();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取附近的人(当前在线的所有人)
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static object GetNearRiderData(int pageIndex, int pageSize = 5, double[] point = null)
|
||||
{
|
||||
if (point == null) return null;
|
||||
|
||||
var dict = new List<System.Tuple<double, OnlineUser>>();
|
||||
var allOnlineUsers = onlineUserHelper.OnlineUsers;
|
||||
foreach (var item in allOnlineUsers)
|
||||
{
|
||||
if (item.Id == PubCommData.CurrentUser.Id)
|
||||
{
|
||||
dict.Add(new Tuple<double, OnlineUser>(0, item));
|
||||
continue;
|
||||
}
|
||||
if (item.Point[0] != 0 && item.Point[1] != 0)
|
||||
{
|
||||
var distance = Math.Round(TurfHelper.GetDistances(point, item.Point) / 1000, 2);
|
||||
dict.Add(new Tuple<double, OnlineUser>(distance, item));
|
||||
}
|
||||
}
|
||||
var allList = dict.OrderBy(d => d.Item1);//.Select(d=>d.Item2);
|
||||
var list = allList.Skip((pageIndex - 1) * pageSize).Take(pageSize).ToList();
|
||||
|
||||
var nearData = list.Select(n => new NearRiderModel()
|
||||
{
|
||||
Headimage = n.Item2.HeadImage,
|
||||
Name = n.Item2.Name,
|
||||
Near = n.Item1, //Math.Round(TurfHelper.GetDistances(point, n.Point) / 1000, 2),
|
||||
KGWeight = n.Item2.WeightKg.ToString(),
|
||||
Speed = Math.Round(n.Item2.Speed, 1),
|
||||
CountryImg = ConfigHelper.Host + $"User/GetCountryImg?userid={n.Item2.Id}",
|
||||
IsSelf = n.Item2.IsSelf
|
||||
});
|
||||
|
||||
return new
|
||||
{
|
||||
NearData = nearData,
|
||||
PageCount = (int)Math.Ceiling((double)allList.Count() / pageSize)
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
private class OnlineUserHelper
|
||||
{
|
||||
//public static List<OnlineUser> users { get; private set; }
|
||||
private static readonly object locker = new object();
|
||||
|
||||
|
||||
private readonly List<OnlineUser> onlineUsers = new List<OnlineUser>();
|
||||
public List<OnlineUser> OnlineUsers
|
||||
{
|
||||
get
|
||||
{
|
||||
//if((DateTime.Now - LastActiveTime).TotalSeconds > 1)
|
||||
//{
|
||||
// SetOnlineUser(new List<ReceiveMsgModel>());
|
||||
//}
|
||||
return onlineUsers.ToList();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 设置在线的人员
|
||||
/// </summary>
|
||||
public void SetOnlineUser(List<ReceiveMsgModel> mes)
|
||||
{
|
||||
try
|
||||
{
|
||||
var msgs = RemoveExceptionData(mes);
|
||||
//LastActiveTime = DateTime.Now;
|
||||
var ids = msgs.Where(m => onlineUsers.All(u => u.Id != m.MemberId)).Select(m => m.MemberId);
|
||||
if (ids.Any())
|
||||
{
|
||||
MapApi api = new MapApi();
|
||||
var rangeUser = api.GetOnlineUserInfo(ids).data;
|
||||
onlineUsers.AddRange(rangeUser);
|
||||
}
|
||||
foreach (var user in onlineUsers)
|
||||
{
|
||||
var item = msgs.FirstOrDefault(u => u.MemberId == user.Id);
|
||||
if (item != null)
|
||||
{
|
||||
user.LastActiveTime = DateTime.Now;
|
||||
user.RouteId = item.RouteId;
|
||||
user.Point = item.Point;
|
||||
user.IsCompleted = item.IsCompleted;
|
||||
//user.exit = item.exit;
|
||||
user.EndDistance = item.EndDistance;
|
||||
user.IsVirtual = item.MemberId < 0;
|
||||
user.Speed = item.Speed;
|
||||
user.WeightKg = item.WeightKg;
|
||||
user.PreDistance = item.PreDistance;
|
||||
user.CompetitionId = item.Competitionid;
|
||||
user.Saved = item.Saved;
|
||||
}
|
||||
else
|
||||
{
|
||||
user.PreDistance = user.EndDistance;
|
||||
}
|
||||
}
|
||||
onlineUsers.RemoveAll(u => u.IsLost);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
#if DEBUG
|
||||
throw;
|
||||
#endif
|
||||
//return new List<OnlineUser>();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 去除重复数据,去除坐标为0的数据
|
||||
/// </summary>
|
||||
/// <param name="mes"></param>
|
||||
private List<ReceiveMsgModel> RemoveExceptionData(List<ReceiveMsgModel> mes)
|
||||
{
|
||||
var list = mes.ToList();
|
||||
//去除自己的数据和命令包
|
||||
//mes.RemoveAll(item => item.MemberId == PubCommData.CurrentUser.Id || item.Point[0] == 0);
|
||||
list.RemoveAll(item => item.Point[0] == 0 && item.Point[1] == 0);
|
||||
//去除重复数据
|
||||
list = list.Distinct(new OlineUserComparer()).ToList();
|
||||
|
||||
return list;
|
||||
}
|
||||
public class NearUserComparer : IEqualityComparer<NearRiderModel>
|
||||
{
|
||||
public bool Equals(NearRiderModel x, NearRiderModel y)
|
||||
{
|
||||
if (x == null)
|
||||
return y == null;
|
||||
return x.Name == y.Name;
|
||||
}
|
||||
|
||||
public int GetHashCode(NearRiderModel obj)
|
||||
{
|
||||
if (obj == null)
|
||||
return 0;
|
||||
return obj.Name.GetHashCode();
|
||||
}
|
||||
}
|
||||
|
||||
public class OlineUserComparer : IEqualityComparer<ReceiveMsgModel>
|
||||
{
|
||||
public bool Equals(ReceiveMsgModel x, ReceiveMsgModel y)
|
||||
{
|
||||
if (x == null)
|
||||
return y == null;
|
||||
return x.MemberId == y.MemberId;
|
||||
}
|
||||
|
||||
public int GetHashCode(ReceiveMsgModel obj)
|
||||
{
|
||||
if (obj == null)
|
||||
return 0;
|
||||
return obj.MemberId.GetHashCode();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f01b9ae72517c36488f04fdbbb889f71
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,123 @@
|
||||
using Assets.Scenes.Ride.Scripts.Model;
|
||||
using Assets.Scripts;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Net.Sockets;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Assets.Scenes.Ride.Scripts.Network
|
||||
{
|
||||
public class TcpService1 : IService
|
||||
{
|
||||
private bool isExit = false;
|
||||
private PfTcpClient _tcpClient;
|
||||
private IPEndPoint iPEndPoint;
|
||||
//private Action<List<ReceiveMsgModel>> _action;
|
||||
|
||||
public void Start(Action<List<ReceiveMsgModel>> action)
|
||||
{
|
||||
if (_tcpClient == null)
|
||||
{
|
||||
//if (!IPAddress.TryParse(ConfigHelper.ServerIpAdress, out var ipString))
|
||||
//{
|
||||
// throw new ArgumentException("IP地址不正确");
|
||||
//}
|
||||
|
||||
//服务端端口
|
||||
iPEndPoint = ConfigHelper.TcpAddress;
|
||||
_tcpClient = new PfTcpClient(iPEndPoint.Address.ToString(), 11001, action);
|
||||
_tcpClient.OptionNoDelay = true;
|
||||
//_action = action;
|
||||
|
||||
_tcpClient.ConnectAsync();
|
||||
}
|
||||
}
|
||||
|
||||
public void Send(byte[] dgram, int bytes)
|
||||
{
|
||||
if (_tcpClient == null) return;
|
||||
if (_tcpClient.IsConnected == false) return;
|
||||
//_tcpClient.WriteLine(System.Text.Encoding.ASCII.GetString(dgram));
|
||||
var txt = System.Text.Encoding.ASCII.GetString(dgram);
|
||||
//Debug.WriteLine("发送:"+txt);
|
||||
_tcpClient.Send(txt);
|
||||
}
|
||||
|
||||
public void Close()
|
||||
{
|
||||
isExit = true;
|
||||
_tcpClient.DisconnectAndStop();
|
||||
|
||||
_tcpClient = null;
|
||||
}
|
||||
|
||||
|
||||
class PfTcpClient : NetCoreServer.TcpClient
|
||||
{
|
||||
private bool _stop;
|
||||
Action<List<ReceiveMsgModel>> _action;
|
||||
public PfTcpClient(string address, int port, Action<List<ReceiveMsgModel>> action) : base(address, port)
|
||||
{
|
||||
_action = action;
|
||||
}
|
||||
|
||||
public void DisconnectAndStop()
|
||||
{
|
||||
_stop = true;
|
||||
DisconnectAsync();
|
||||
while (IsConnected)
|
||||
{
|
||||
Thread.Yield();
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnConnected()
|
||||
{
|
||||
base.OnConnected();
|
||||
}
|
||||
|
||||
protected override void OnDisconnected()
|
||||
{
|
||||
//base.OnDisconnected();
|
||||
Debug.WriteLine("tcp断线,3秒后重连");
|
||||
Thread.Sleep(3000);
|
||||
|
||||
if (!_stop)
|
||||
{
|
||||
ConnectAsync();
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnReceived(byte[] buffer, long offset, long size)
|
||||
{
|
||||
//base.OnReceived(buffer, offset, size);
|
||||
var returnData = Encoding.UTF8.GetString(buffer, (int)offset, (int)size);
|
||||
//Debug.WriteLine("收到:" + returnData+"\r\n");
|
||||
//System.IO.File.AppendAllText(System.Environment.CurrentDirectory + "接收到的数据.txt", returnData.Trim().Replace("\0", "")+"\r\n", Encoding.UTF8);
|
||||
var list = new List<ReceiveMsgModel>();
|
||||
var itemList = returnData.Split('|');
|
||||
|
||||
foreach (var item in itemList)
|
||||
{
|
||||
var info = ReceiveMsgModel.Parse(item);
|
||||
if (info != null)
|
||||
{
|
||||
list.Add(info);
|
||||
}
|
||||
}
|
||||
_action(list);
|
||||
}
|
||||
|
||||
protected override void OnError(SocketError error)
|
||||
{
|
||||
//base.OnError(error);
|
||||
Debug.WriteLine(error);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7d27070ad7cfef3418e8f764a42c08a7
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,94 @@
|
||||
using Assets.Scenes.Ride.Scripts.Model;
|
||||
using Assets.Scripts;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Net.Sockets;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Assets.Scenes.Ride.Scripts.Network
|
||||
{
|
||||
public class UdpService : IService
|
||||
{
|
||||
private bool isExit = false;
|
||||
private UdpClient udpClient;
|
||||
private IPEndPoint iPEndPoint;
|
||||
|
||||
public void Start(Action<List<ReceiveMsgModel>> action)
|
||||
{
|
||||
if (udpClient == null)
|
||||
{
|
||||
//if (!IPAddress.TryParse(ConfigHelper.ServerIpAdress, out var ipString))
|
||||
//{
|
||||
// throw new ArgumentException("IP地址不正确");
|
||||
//}
|
||||
|
||||
//服务端端口
|
||||
iPEndPoint = ConfigHelper.UdpAddress;
|
||||
udpClient = new UdpClient();
|
||||
uint IOC_IN = 0x80000000;
|
||||
uint IOC_VENDOR = 0x18000000;
|
||||
uint SIO_UDP_CONNRESET = IOC_IN | IOC_VENDOR | 12;
|
||||
udpClient.Client.IOControl((int)SIO_UDP_CONNRESET, new byte[] { Convert.ToByte(false) }, null);
|
||||
udpClient.Client.ReceiveTimeout = 5000;//这里如果不设置超时,会导致整个应用程序阻塞。
|
||||
udpClient.Client.SendTimeout = 5000;
|
||||
udpClient.Connect(iPEndPoint);
|
||||
//heartbeat = new System.Timers.Timer();
|
||||
//heartbeat.Interval = 1000;//20秒一次心跳包
|
||||
//heartbeat.AutoReset = true;
|
||||
//heartbeat.Enabled = true;
|
||||
//heartbeat.Elapsed += Heartbeat_Elapsed;
|
||||
|
||||
Task.Run(async () =>
|
||||
{
|
||||
while (isExit == false)
|
||||
{
|
||||
try
|
||||
{
|
||||
byte[] receiveBytes = udpClient.Receive(ref iPEndPoint);
|
||||
var returnData = Encoding.ASCII.GetString(receiveBytes);
|
||||
var list = new List<ReceiveMsgModel>();
|
||||
var itemList = returnData.Split('|');
|
||||
|
||||
foreach (var item in itemList)
|
||||
{
|
||||
var info = ReceiveMsgModel.Parse(item);
|
||||
if (info != null)
|
||||
{
|
||||
list.Add(info);
|
||||
}
|
||||
}
|
||||
action(list);
|
||||
}
|
||||
catch (SocketException ex)
|
||||
{
|
||||
await Task.Delay(6000);
|
||||
if (isExit == false && udpClient != null)
|
||||
{
|
||||
udpClient.Connect(iPEndPoint);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public void Send(byte[] dgram, int bytes)
|
||||
{
|
||||
udpClient?.Send(dgram, bytes);
|
||||
}
|
||||
|
||||
public void Close()
|
||||
{
|
||||
isExit = true;
|
||||
udpClient?.Close();
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 170d4696cbfb82743a9189608d3a162a
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in new issue
Block a user