loading页&结果页面&代码结构微调

This commit is contained in:
lishuo committed 2021-07-16 18:37:02 +08:00
1 parent eb1803c9ef
commit eed2d13624
99 files changed
+14567 -7299

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,472 @@
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.IO;
using System.IO.Compression;
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(int competitionid = 0, bool isWatch = false)
{
try
{
Competitionid = competitionid;
IsWatch = isWatch;
//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();
//告诉tcp服务器gzip
}
}
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();
}
}
public static byte[] Compress(string text)
{
var bytes = Encoding.Unicode.GetBytes(text);
using (var mso = new MemoryStream())
{
using (var gs = new GZipStream(mso, CompressionMode.Compress))
{
gs.Write(bytes, 0, bytes.Length);
}
return mso.ToArray();
}
}
public static string Decompress(byte[] data)
{
// Read the last 4 bytes to get the length
byte[] lengthBuffer = new byte[4];
Array.Copy(data, data.Length - 4, lengthBuffer, 0, 4);
int uncompressedSize = BitConverter.ToInt32(lengthBuffer, 0);
var buffer = new byte[uncompressedSize];
using (var ms = new MemoryStream(data))
{
using (var gzip = new GZipStream(ms, CompressionMode.Decompress))
{
gzip.Read(buffer, 0, uncompressedSize);
}
}
return Encoding.Unicode.GetString(buffer);
}
/// <summary>
/// 发送心跳包
/// </summary>
private static void SendHeartbeat()
{
try
{
var model = new
{
CommandType = 0,
};
var sendBytes = Encoding.UTF8.GetBytes(Newtonsoft.Json.JsonConvert.SerializeObject(model));
_udpService.Send(sendBytes, sendBytes.Length);
}
catch (Exception e)
{
Console.WriteLine("发送心跳失败:" + e);
}
}
public static int Competitionid { get; set; }
public static bool IsWatch { get; set; }
/// <summary>
/// 告诉TCP服务器给我Gzip的格式
/// </summary>
public static void SendGizpModel()
{
try
{
var model = new GzipMsgModel
{
CommandType = 2,
V = 2,
Encoding = "gzip",
Client = App.AppVersion,
MemberId = App.CurrentUser.Id,
Competitionid = Competitionid,
IsWatch = IsWatch
};
var sendBytes = Encoding.UTF8.GetBytes(Newtonsoft.Json.JsonConvert.SerializeObject(model));
_udpService.Send(sendBytes, sendBytes.Length);
}
catch (Exception e)
{
Console.WriteLine("发送失败:" + e);
}
}
/// <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
{
Point[0] = Math.Round(Point[0], 6, MidpointRounding.AwayFromZero);
Point[1] = Math.Round(Point[1], 6, MidpointRounding.AwayFromZero);
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, App.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)
{
var result = onlineUserHelper.OnlineUsers.Where(u => routeId.Contains(u.RouteId) && u.CompetitionId == 0).ToList();
return result;
}
//比赛中的人只能看到当前比赛的人
public static List<OnlineUser> GetCompetitionOnlineUsers(int competitionId)
{
//var result = onlineUserHelper.OnlineUsers.Where(u => u.CompetitionId == competitionId && !u.IsWatcher).ToList();
var result = onlineUserHelper.OnlineUsers.Where(u =>!u.IsWatcher).ToList();
return result;
}
//当前比赛观察者
public static List<OnlineUser> GetCompetitionWatchers(int competitionId,int size = 5)
{
//var result = onlineUserHelper.OnlineUsers.Where(u => u.CompetitionId == competitionId && u.IsWatcher).Take(size).ToList();
var result = onlineUserHelper.OnlineUsers.Where(u =>u.IsWatcher).Take(size).ToList();
return result;
}
public static int GetNearRiderCount()
{
return onlineUserHelper.OnlineUsers.Count();
}
/// <summary>
/// 获取附近的人(当前在线的所有人)
/// </summary>
/// <returns></returns>
public static IList<NearRiderModel> 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 == App.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 = App.Host + $"User/GetCountryImg?userid={n.Item2.Id}",
IsSelf = n.Item2.IsSelf,
Id = n.Item2.Id,
Country = n.Item2.Country,
}).ToList();
return nearData;
//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;
user.WatcherList = new List<int>();
foreach (var o in item.WatchIdList.Split('|'))
{
if (!string.IsNullOrEmpty(o))
{
user.WatcherList.Add(Convert.ToInt32(o));
}
}
user.IsWatcher = user.WatcherList.Contains(item.MemberId);
}
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 == App.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,183 @@
using Assets.Scenes.Ride.Scripts.Model;
using Assets.Scripts;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.IO.Compression;
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 = App.TcpAddress;
_tcpClient = new PfTcpClient(iPEndPoint.Address.ToString(), iPEndPoint.Port, 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();
MapUDPService.SendGizpModel();
}
protected override void OnDisconnected()
{
//base.OnDisconnected();
Debug.WriteLine("tcp断线,3秒后重连");
Thread.Sleep(3000);
if (!_stop)
{
ConnectAsync();
}
}
public string Decompress(byte[] data)
{
// Read the last 4 bytes to get the length
byte[] lengthBuffer = new byte[4];
Array.Copy(data, data.Length - 4, lengthBuffer, 0, 4);
int uncompressedSize = BitConverter.ToInt32(lengthBuffer, 0);
var buffer = new byte[uncompressedSize];
using (var ms = new MemoryStream(data))
{
using (var gzip = new GZipStream(ms, CompressionMode.Decompress))
{
gzip.Read(buffer, 0, uncompressedSize);
}
}
return Encoding.UTF8.GetString(buffer);
}
private string temp = "";
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);
//*sdfsd#*sdfsd#*sdfsd#*sdfsd#
foreach (var item in returnData)
{
if (item != '*' && item != '#')
{
temp += item;
}
if (item == '#')
{
//解压 temp
var uncompressStr = Decompress(Convert.FromBase64String(temp));
#if UNITY_EDITOR
Console.WriteLine(uncompressStr);
#endif
var list = new List<ReceiveMsgModel>();
//数据解析 l{},w{1|2|3|4} l:列表 w:观察者模式
var arr = uncompressStr.Split(';');
foreach (var t in arr)
{
//列表
if (t.IndexOf('l') == 0)
{
var l = t.Replace("l{", "").Replace("}", "");
var itemList = l.Split('|');
temp = "";
foreach (var obj in itemList)
{
var info = ReceiveMsgModel.Parse(obj);
if (info != null)
{
list.Add(info);
}
}
}
//观察者
if (t.IndexOf('w') == 0)
{
var w = t.Replace("w{", "").Replace("}", "");
foreach (var o in list)
{
o.WatchIdList = w;
}
}
}
_action(list);
}
}
//Debug.WriteLine("收到:" + returnData+"\r\n");
//System.IO.File.AppendAllText(System.Environment.CurrentDirectory + "接收到的数据.txt", returnData.Trim().Replace("\0", "")+"\r\n", Encoding.UTF8);
}
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 = App.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: