358 lines
11 KiB
C#
358 lines
11 KiB
C#
|
using Chat.Framework.WXSdk.Implement;
|
|||
|
using CsharpHttpHelper;
|
|||
|
using Newtonsoft.Json;
|
|||
|
using Newtonsoft.Json.Linq;
|
|||
|
using System;
|
|||
|
using System.Collections.Generic;
|
|||
|
using System.Linq;
|
|||
|
using System.Net;
|
|||
|
using System.Text;
|
|||
|
using System.Threading;
|
|||
|
using System.Threading.Tasks;
|
|||
|
using WechatProto;
|
|||
|
using static Chat.Framework.WXSdk.IPAD.SocketClient;
|
|||
|
|
|||
|
namespace Chat.Framework.WXSdk.IPAD
|
|||
|
{
|
|||
|
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// 微信Socket
|
|||
|
/// </summary>
|
|||
|
public class WechatSocket
|
|||
|
{
|
|||
|
|
|||
|
private WXClientImpl_IPAD client;
|
|||
|
public void TestError()
|
|||
|
{
|
|||
|
SocketExceptionCallback( WXSocketClientError.connetedErr,this._socket);
|
|||
|
//this._socket.SocketExceptionCallback(WXSocketClientError.connetedErr);
|
|||
|
}
|
|||
|
public WechatSocket(WXClientImpl_IPAD client)
|
|||
|
{
|
|||
|
this.client = client;
|
|||
|
}
|
|||
|
///// <summary>
|
|||
|
///// 微信Socket
|
|||
|
///// </summary>
|
|||
|
//private SocketClient<WeChatMessage> _socket;
|
|||
|
private SocketClient _socket;
|
|||
|
|
|||
|
public void ClearPack()
|
|||
|
{
|
|||
|
if (this._socket != null) this._socket.ClearPack();
|
|||
|
}
|
|||
|
public bool IsStop { get;private set; }
|
|||
|
/// <summary>
|
|||
|
/// 停止
|
|||
|
/// </summary>
|
|||
|
public void Stop()
|
|||
|
{
|
|||
|
try
|
|||
|
{
|
|||
|
if (_socket != null)
|
|||
|
{
|
|||
|
_socket.Disconnect();
|
|||
|
}
|
|||
|
//_socket?.Stop();
|
|||
|
//_socket?.UnRegisterEndPoint("WeChat");
|
|||
|
|
|||
|
//_socketServers.Clear();
|
|||
|
//_httpServers.Clear();
|
|||
|
|
|||
|
if (_socket != null) _socket = null;
|
|||
|
}
|
|||
|
catch
|
|||
|
{
|
|||
|
// ignored
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
public string ServerIp { get; set; }
|
|||
|
/// <summary>
|
|||
|
/// 连接腾讯服务器
|
|||
|
/// </summary>
|
|||
|
/// <param name="ipList"></param>
|
|||
|
/// <returns></returns>
|
|||
|
public bool Connect()
|
|||
|
{
|
|||
|
|
|||
|
this.Stop();
|
|||
|
ServerIp = this.client.Host.GetLong();
|
|||
|
this._socket = new SocketClient(new DnsEndPoint(ServerIp, 443), this.client);
|
|||
|
this._socket.NotifyCallback = (byte[] data) =>
|
|||
|
{
|
|||
|
int cmd = WXClientTool.ReadInt(data, 8);
|
|||
|
switch (cmd)
|
|||
|
{
|
|||
|
case 24:
|
|||
|
if (Util.HexToStr(data) == "0000001400100001000000180000000000000100")
|
|||
|
{
|
|||
|
//朋友圈更新Notify
|
|||
|
//Client.SyncMessage(true);
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
//普通消息Notify
|
|||
|
Task.Factory.StartNew(client.AsyncSyncMessage);
|
|||
|
}
|
|||
|
break;
|
|||
|
case 318:
|
|||
|
client.DecodeSecureNotifyThread(data);
|
|||
|
break;
|
|||
|
default:
|
|||
|
Console.WriteLine($"ReceivedUnKnowMessage CMD:" + cmd);
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
return true;
|
|||
|
};
|
|||
|
this._socket.SocketExceptionCallback = SocketExceptionCallback;
|
|||
|
return this._socket.Connect();
|
|||
|
}
|
|||
|
|
|||
|
object lock_obj = new object();
|
|||
|
|
|||
|
private bool SocketExceptionCallback(SocketClient.WXSocketClientError error, SocketClient socketClient)
|
|||
|
{
|
|||
|
lock (lock_obj)
|
|||
|
{
|
|||
|
try
|
|||
|
{
|
|||
|
if (socketClient != null && socketClient == this._socket && socketClient.connected)
|
|||
|
{
|
|||
|
socketClient.Connect();
|
|||
|
if (client.Status == WxStatus.在线) client.AsyncSyncMessage();
|
|||
|
}
|
|||
|
}
|
|||
|
catch (Exception)
|
|||
|
{
|
|||
|
}
|
|||
|
return true;
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
///// <summary>
|
|||
|
///// Socket中断
|
|||
|
///// </summary>
|
|||
|
///// <param name="connection"></param>
|
|||
|
//private void WeChatClient_ReceivedOnDisconnected(Sodao.FastSocket.SocketBase.IConnection connection)
|
|||
|
//{
|
|||
|
// if (connection.RemoteEndPoint != null)
|
|||
|
// OnReceivedOnDisconnected(connection.RemoteEndPoint.Address);
|
|||
|
//}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
///// <summary>
|
|||
|
///// 收到通知包
|
|||
|
///// </summary>
|
|||
|
///// <param name="connection"></param>
|
|||
|
///// <param name="message"></param>
|
|||
|
//private void WeChatClient_ReceivedNotifyMessage(Sodao.FastSocket.SocketBase.IConnection connection, WeChatMessage message)
|
|||
|
//{
|
|||
|
// if (message != null) OnReceivedNotifyMessage(message);
|
|||
|
//}
|
|||
|
|
|||
|
///// <summary>
|
|||
|
///// 收到未知信息
|
|||
|
///// </summary>
|
|||
|
///// <param name="arg1"></param>
|
|||
|
///// <param name="arg2"></param>
|
|||
|
//private void WeChatClient_ReceivedUnknowMessage(IConnection arg1, WeChatMessage arg2)
|
|||
|
//{
|
|||
|
// try
|
|||
|
// {
|
|||
|
// int Ret = Sodao.FastSocket.SocketBase.Utils.NetworkBitConverter.ToInt32(arg2.Msg.BaseMsg.Payloads.ToByteArray(), 18);
|
|||
|
// Console.WriteLine("ReceivedUnknowMessage CMD" + arg2.CmdID + " 异常返回Ret:" + Ret);
|
|||
|
// if (Ret == -13 && client.Status == WxStatus.在线)
|
|||
|
// {
|
|||
|
// client.WriteLog($"ReceivedUnknowMessage CMD" + arg2.CmdID + " -13 Need AutoLogin");
|
|||
|
// client.ResetConnection();
|
|||
|
// }
|
|||
|
// }
|
|||
|
// catch (Exception)
|
|||
|
// {
|
|||
|
// }
|
|||
|
//}
|
|||
|
|
|||
|
///// <summary>
|
|||
|
///// 发包到腾讯
|
|||
|
///// </summary>
|
|||
|
///// <param name="pack"></param>
|
|||
|
///// <returns></returns>
|
|||
|
//public byte[] SendToWeChat(WechatMsg pack)
|
|||
|
//{
|
|||
|
// if (pack == null) return null;
|
|||
|
|
|||
|
// if (_socket == null) Connect();
|
|||
|
|
|||
|
// if (pack.BaseMsg.LongHead.Length < 16 && !string.IsNullOrEmpty(pack.BaseMsg.CmdUrl))
|
|||
|
// {
|
|||
|
// Console.WriteLine($"UnKnow pack");
|
|||
|
// return null;
|
|||
|
// }
|
|||
|
|
|||
|
// var buffers = new byte[pack.BaseMsg.LongHead.Length + pack.BaseMsg.Payloads.Length];
|
|||
|
// var head = pack.BaseMsg.LongHead.ToByteArray();
|
|||
|
// var body = pack.BaseMsg.Payloads.ToByteArray();
|
|||
|
|
|||
|
// try
|
|||
|
// {
|
|||
|
// if (head.Length > 0)
|
|||
|
// {
|
|||
|
// Buffer.BlockCopy(head, 0, buffers, 0, 16);
|
|||
|
// Buffer.BlockCopy(body, 0, buffers, 16, body.Length);
|
|||
|
// }
|
|||
|
// else
|
|||
|
// {
|
|||
|
// Buffer.BlockCopy(body, 0, buffers, 0, body.Length);
|
|||
|
// }
|
|||
|
// }
|
|||
|
// catch
|
|||
|
// {
|
|||
|
// return null;
|
|||
|
// }
|
|||
|
|
|||
|
// return SendToWeChat(pack.BaseMsg.Cmd, buffers).Result;
|
|||
|
//}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// 发包到腾讯
|
|||
|
/// </summary>
|
|||
|
/// <param name="cmd"></param>
|
|||
|
/// <param name="buffers"></param>
|
|||
|
/// <returns></returns>
|
|||
|
public Task<byte[]> SendToWeChat(int cmd, byte[] buffers)
|
|||
|
{
|
|||
|
return null;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
public void SendToWechat(byte[] buffers,string text="")
|
|||
|
{
|
|||
|
if (_socket == null || !_socket.connected)
|
|||
|
Connect();
|
|||
|
|
|||
|
this._socket.AsynSend(buffers);
|
|||
|
}
|
|||
|
|
|||
|
public byte[] GetResult(int seq)
|
|||
|
{
|
|||
|
if (_socket != null) return this._socket.GetBuffBySeq(seq);
|
|||
|
return null;
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// 短链发送包
|
|||
|
/// </summary>
|
|||
|
/// <param name="pack"></param>
|
|||
|
/// <returns></returns>
|
|||
|
public byte[] SendWeChatPost(WechatMsg pack)
|
|||
|
{
|
|||
|
var body = pack.BaseMsg.Payloads.ToByteArray();
|
|||
|
|
|||
|
var result = SendWeChatPost(body, pack.BaseMsg.CmdUrl);
|
|||
|
|
|||
|
return result;
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// 短链发送包
|
|||
|
/// </summary>
|
|||
|
/// <param name="body"></param>
|
|||
|
/// <param name="cmdUrl"></param>
|
|||
|
/// <returns></returns>
|
|||
|
public byte[] SendWeChatPost(byte[] body, string cmdUrl, int retry_number = 2)
|
|||
|
{
|
|||
|
|
|||
|
// var tryTime = 3;
|
|||
|
again:
|
|||
|
//"short.weixin.qq.com";
|
|||
|
var baseUrl = client.Host.GetSort();
|
|||
|
|
|||
|
HttpResult result = null;
|
|||
|
try
|
|||
|
{
|
|||
|
var http = new HttpHelper();
|
|||
|
var header = new HttpItem()
|
|||
|
{
|
|||
|
URL = "http://" + baseUrl + cmdUrl,
|
|||
|
Method = "POST",
|
|||
|
PostdataByte = body,
|
|||
|
PostDataType = CsharpHttpHelper.Enum.PostDataType.Byte,
|
|||
|
Timeout = 10000,
|
|||
|
ReadWriteTimeout = 10000,
|
|||
|
UserAgent = "MicroMessenger Client",
|
|||
|
ContentType = "application/octet-stream",
|
|||
|
Accept = "*/*",
|
|||
|
ResultType = CsharpHttpHelper.Enum.ResultType.Byte
|
|||
|
};
|
|||
|
|
|||
|
result = http.GetHtml(header);
|
|||
|
}
|
|||
|
catch (Exception ex)
|
|||
|
{
|
|||
|
Console.WriteLine(ex.Message);
|
|||
|
}
|
|||
|
|
|||
|
if (result?.StatusCode == HttpStatusCode.OK && result?.ResultByte != null)
|
|||
|
{
|
|||
|
return result.ResultByte;
|
|||
|
}
|
|||
|
|
|||
|
if (retry_number > 0)
|
|||
|
{
|
|||
|
// baseUrl = client.Host.GetSort();
|
|||
|
retry_number--;
|
|||
|
Thread.Sleep(10);
|
|||
|
goto again;
|
|||
|
}
|
|||
|
|
|||
|
return null;
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// 连接成功
|
|||
|
/// </summary>
|
|||
|
public event EventHandler<IPAddress> ReceivedOnConnected;
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// 连接断开
|
|||
|
/// </summary>
|
|||
|
public event EventHandler<IPAddress> ReceivedOnDisconnected;
|
|||
|
|
|||
|
///// <summary>
|
|||
|
///// 收到通知包
|
|||
|
///// </summary>
|
|||
|
//public event EventHandler<WeChatMessage> ReceivedNotifyMessage;
|
|||
|
|
|||
|
///// <summary>
|
|||
|
///// 收到通知包
|
|||
|
///// </summary>
|
|||
|
///// <param name="e"></param>
|
|||
|
//protected virtual void OnReceivedNotifyMessage(WeChatMessage e) => ReceivedNotifyMessage?.Invoke(this, e);
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// 连接成功
|
|||
|
/// </summary>
|
|||
|
/// <param name="e"></param>
|
|||
|
protected virtual void OnReceivedOnConnected(IPAddress e) => ReceivedOnConnected?.Invoke(this, e);
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// 连接断开
|
|||
|
/// </summary>
|
|||
|
/// <param name="e"></param>
|
|||
|
protected virtual void OnReceivedOnDisconnected(IPAddress e) => ReceivedOnDisconnected?.Invoke(this, e);
|
|||
|
}
|
|||
|
}
|