old_flsystem/类库/Chat.Framework/WXSdk/IPAD/SocketTest.cs

338 lines
9.7 KiB
C#
Raw Permalink Normal View History

2022-09-20 03:10:29 +00:00
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);
}
}
}
/// <summary>
/// 通过seq取微信服务器返回的socket包数据
/// </summary>
/// <param name="Seq"></param>
/// <returns></returns>
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<int, SocketResult> mPackDic = new Dictionary<int, SocketResult>();
public WXClientImpl_IPAD weixin;
public Func<byte[], bool> 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<ProtobufPackageInfo>
{
public IReceiveFilter<ProtobufPackageInfo> 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<BufferedPackageInfo>
{
public IReceiveFilter<BufferedPackageInfo> 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<System.ArraySegment<byte>>() {
new ArraySegment<byte>(buffer)
});
}
public void Reset()
{
NextReceiveFilter = null;
}
}
}