using Chat.Framework.WXSdk.Implement; using System; using System.Collections.Generic; using System.Linq; using System.Net; using System.Text; using System.Threading.Tasks; using SuperSocket.ClientEngine; using SuperSocket.ProtoBase; namespace Chat.Framework.WXSdk.IPAD { public class SocketTest { DnsEndPoint hostEndPoint; public SocketTest(DnsEndPoint hostEndPoint, WXClientImpl_IPAD weixin) { this.weixin = weixin; this.hostEndPoint = hostEndPoint; } public bool connected { get { return Client != null ? Client.IsConnected : false; } } private EasyClient Client; public bool Connect() { this.Disconnect(); Client = new EasyClient(); Client.Initialize(new ProtobufReceiveFilter(), (request) => { Client_OnReceive(request.buffer); }); Client.Error += Client_Error; Client.Closed += Client_Closed; var _connected = Client.ConnectAsync(this.hostEndPoint); return _connected.Result; } private void Client_Closed(object sender, EventArgs e) { LogHelper.GetSingleObj().Error("Socket_Error", $"{weixin.WeixinHao}-Socket Close"); } private void Client_Error(object sender, ErrorEventArgs e) { try { LogHelper.GetSingleObj().Error("Socket_Error", $"{weixin.WeixinHao}-Socket Error"); if (this.weixin.Status == WxStatus.在线) { if (this.Connect()) { this.weixin.AsyncSyncMessage(); } } } catch (Exception) { } } private void Client_OnReceive(byte[] obj) { //Console.WriteLine($"Push接收长度[{obj.Length}] {random.Next(1, 9999)}"); try { DePack(obj); } catch (Exception) { } } public void AsynSend(byte[] data, string text = "") { try { Client.Send(data); } catch (Exception) { } } public void Disconnect() { try { if (this.Client != null) { this.Client.Close(); this.Client = null; } } catch (Exception) { } } public void ClearPack() { lock (mPackDic) { var vas = mPackDic.ToList().Where(f => f.Value.Time < DateTime.Now.AddMinutes(-5)); foreach (var item in vas) { mPackDic.Remove(item.Key); } } } /// /// 通过seq取微信服务器返回的socket包数据 /// /// /// public byte[] GetBuffBySeq(int Seq) { lock (mPackDicLock) { //Thread.Sleep(10); byte[] buf = null; try { if (mPackDic.ContainsKey(Seq)) { buf = mPackDic[Seq].Data; mPackDic.Remove(Seq); return buf; } } catch (Exception ee) { LogHelper.GetSingleObj().Error("Wechat GetBuffBySeq", $"{weixin.WeixinHao}- 获取超时!{ee.Message}"); } return buf; } } private object mPackDicLock = new object(); private byte[] packageData = null; public bool DePack(byte[] bys) { bool result = false; int x = bys.Length; if (packageData != null) { byte[] temp = new byte[packageData.Length + x]; Buffer.BlockCopy(packageData, 0, temp, 0, packageData.Length); Buffer.BlockCopy(bys, 0, temp, packageData.Length, x); packageData = temp; } else { packageData = new byte[x]; Buffer.BlockCopy(bys, 0, packageData, 0, x); } while (packageData != null && packageData.Length > 16) { int newPackageLength = WXClientTool.ReadInt(packageData, 0); if (newPackageLength <= 0 || newPackageLength > 8000000) { LogHelper.GetSingleObj().Error("Wechat DePack", "长度不合法"); packageData = null; } else if (newPackageLength <= packageData.Length) { byte[] newPackage = new byte[newPackageLength]; Buffer.BlockCopy(packageData, 0, newPackage, 0, newPackageLength); if (newPackageLength < packageData.Length) { byte[] temData = new byte[packageData.Length - newPackageLength]; Buffer.BlockCopy(packageData, newPackageLength, temData, 0, packageData.Length - newPackageLength); packageData = temData; } else { packageData = null; } HandlePackage(newPackage); } else { break; } } return result; } //解析包 public void HandlePackage(byte[] bys) { if (bys.Length == 20 && bys[3] == 20 && bys[5] == 16 && bys[7] == 1) { // 有新消息就会接受到此包 SaveBufferToPackDic(bys); return; } else { if (bys.Length >= 16 && bys[16] != (byte)191 && !(bys[3] == 58 && bys[5] == 16 && bys[7] == 1 && bys.Length == 58) && !(bys[3] == 47 && bys[5] == 16 && bys[7] == 1 && bys.Length == 47)) { return; } SaveBufferToPackDic(bys); } } class SocketResult { public DateTime Time { get; set; } public byte[] Data { get; set; } } Dictionary mPackDic = new Dictionary(); public WXClientImpl_IPAD weixin; public Func NotifyCallback { get; set; } // int Seq = 0; //保存数据到mPackDic public void SaveBufferToPackDic(byte[] bys) { lock (mPackDicLock) { var Seq = WXClientTool.ReadInt(bys, 12); if (Seq == 0) { byte[] buffers = new byte[bys.Length]; Buffer.BlockCopy(bys, 0, buffers, 0, bys.Length); int cmd = WXClientTool.ReadInt(buffers, 8); int selector = WXClientTool.ReadInt(buffers, 16); LogHelper.GetSingleObj().Info("Wechat SaveBufferToPackDic", $"{weixin.WeixinHao}-收到{buffers.Length}字节!"); if (cmd == 318 && NotifyCallback != null) { NotifyCallback(buffers); } if (cmd == 24 && NotifyCallback != null) { NotifyCallback(buffers); } if (cmd != 24 && cmd != 318) { } } else { byte[] buffers = new byte[bys.Length]; Buffer.BlockCopy(bys, 0, buffers, 0, bys.Length); mPackDic[Seq] = new SocketResult() { Data = buffers, Time = DateTime.Now }; Seq = 0; } } } } public class ProtobufPackageInfo : IPackageInfo { public byte[] buffer { get; set; } } public class ProtobufReceiveFilter : IReceiveFilter { public IReceiveFilter NextReceiveFilter { get; protected set; } public FilterState State => FilterState.Normal; public ProtobufPackageInfo Filter(BufferList data, out int rest) { rest = 0; var list = data.Last; byte[] buffer = new byte[list.Count]; Array.Copy(list.Array, buffer, list.Count); return new ProtobufPackageInfo() { buffer = buffer }; } public void Reset() { NextReceiveFilter = null; } } public class MyReceiveFilter : SuperSocket.ProtoBase.IReceiveFilter { public IReceiveFilter NextReceiveFilter { get; protected set; } public FilterState State => FilterState.Normal; public BufferedPackageInfo Filter(BufferList data, out int rest) { rest=0; var list = data.Last; byte[] buffer = new byte[list.Count]; Array.Copy(list.Array, buffer, list.Count); return new BufferedPackageInfo("wx", new List>() { new ArraySegment(buffer) }); } public void Reset() { NextReceiveFilter = null; } } }