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; using NetCoreServer; using Assets.Scripts.Apis.Models; namespace Assets.Scenes.Ride.Scripts.Network { public class TcpService1 : IService { private bool isExit = false; private PfTcpClient _tcpClient; private IPEndPoint iPEndPoint; //private Action> _action; public void Start(Action> 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.UTF8.GetString(dgram); //Debug.WriteLine("发送:"+txt); try { _tcpClient.SendAsync(txt); } catch (Exception e) { Console.WriteLine(e); } } public void Disconnect() { try { _tcpClient.DisconnectAsync(); } catch (Exception e) { Console.WriteLine(e); } } public void Close() { try { isExit = true; _tcpClient.DisconnectAndStop(); _tcpClient = null; } catch(Exception e) { Console.WriteLine(e); } } class PfTcpClient : NetCoreServer.TcpClient { private bool _stop; Action> _action; public PfTcpClient(string address, int port, Action> action) : base(address, port) { _action = action; } public void DisconnectAndStop() { _stop = true; Task.Run(() => { DisconnectAsync(); }); //while (IsConnected) //{ // Thread.Yield(); //} } protected override void OnConnected() { base.OnConnected(); MapUDPService.SendGizpModel(); } protected override void OnDisconnected() { //base.OnDisconnected(); //Console.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 StringBuilder temp = new StringBuilder(); 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.Append(item); } if (item == '#') { //解压 temp var uncompressStr = Decompress(Convert.FromBase64String(temp.ToString())); #if UNITY_EDITOR Console.WriteLine(uncompressStr); #endif var list = new List(); //数据解析 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.Clear(); 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; } } //房间信息 if (t.IndexOf('g') == 0) { var x = t.Replace("g{", "").Replace("}", ""); //l2[0,0,321313,30,5,5492,福州化工路-鼓山峰爬坡线路,19.17906,815.9704000000002,4.0466336723489045,True,False,True,213,,,http://192.168.0.102:5082/Map/AltitudeGraph?id=5492,0,:][0,0,2131,30,4,5492,福州化工路-鼓山峰爬坡线路,19.17906,815.9704000000002,4.0466336723489045,True,False,True,313,,,http://192.168.0.102:5082/Map/AltitudeGraph?id=5492,0,:][20,16652,3213,30,3,5492,福州化工路-鼓山峰爬坡线路,19.17906,815.9704000000002,4.0466336723489045,True,False,True,,,,http://192.168.0.102:5082/Map/AltitudeGraph?id=5492,0,2022/5/6 8:41:34:][19,16652,测试3d线路,30,2,5492,福州化工路-鼓山峰爬坡线路,19.17906,815.9704000000002,4.0466336723489045,True,False,True,,,,http://192.168.0.102:5082/Map/AltitudeGraph?id=5492,0,2022/5/6 1:39:57:][18,16652,测试,61,2,5492,福州化工路-鼓山峰爬坡线路,19.17906,815.9704000000002,4.0466336723489045,True,False,True,,,,http://192.168.0.102:5082/Map/AltitudeGraph?id=5492,0,2022/4/25 2:34:03:][17,16652,213,30,3,1217,翠屏山后山北向南,5.271609999999998,65.22760000000001,0.23308249282477278,False,False,True,,,,http://192.168.0.102:5082/Map/AltitudeGraph?id=1217,0,2022/4/25 2:20:13:] if (!string.IsNullOrEmpty(x)) { var index = x.IndexOf("l"); var total = 0; if (index != -1) { var pageInfo = x.Substring(0, index); if (!string.IsNullOrEmpty(pageInfo)) total = Convert.ToInt32(pageInfo); x = x.Substring(index); } var li = GameRoomModel.Parse(x); foreach (var i in list) { i.RoomList = li; i.GameRoomTotal = total; } } } //附加信息 if (t.IndexOf('e') == 0) { var g = t.Replace("e{", "").Replace("}", ""); var glist = g.Split('|'); foreach (var i in glist) { if (string.IsNullOrEmpty(i)) continue; var extendInfo = ExtendInfo.Parse(i); var owner = list.Where(c => c.MemberId == extendInfo.UserId && c.TotoalTicks == extendInfo.TotalTicks).FirstOrDefault(); if (owner != null) { owner.RoomId = extendInfo.RoomId; owner.FrameRate = extendInfo.FrameRate; } } } } _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); Console.WriteLine("出错后重启"); Debug.WriteLine(error); } } } }