using CsharpHttpHelper; using PCRobot.Pack; using PCRobot.PCWechat; using SuperSocket.ClientEngine; using System; using System.Collections.Generic; using System.Linq; using System.Net; using System.Text; using System.Threading; using System.Threading.Tasks; namespace PCRobot { public class EasySoc { private static EasySoc _socket; public static EasySoc GetSocket() { if (_socket == null) _socket = new EasySoc(); return _socket; } public EasySoc() { timer = new System.Threading.Timer(new TimerCallback(timerCall), null, 0, 1000 * 5); } public bool IsConnected { get { if (client != null && client.IsConnected) return true; return false; } } public bool Stop { get; set; } AsyncTcpSession client; //EasyClient client; private readonly static object session_lock = new object(); public void Close(bool isQuit = false) { try { lock (session_lock) { if (client != null) { if (isQuit) timer.Dispose(); //client.DataReceived -= Client_DataReceived; client.Connected -= Client_Connected; client.Closed -= Client_Closed; client.Error -= Client_Error; client.Close(); client = null; } } } catch (Exception ex) { if (WechatClient.IsLog) LogHelper.GetSingleObj().Info("Close ERROR:", $"{ex.Message}"); LogHelper.GetSingleObj().Error("Close ERROR:", $"{ex.Message} - {ex.StackTrace}"); } } IPEndPoint endPoint; private Action ReceiveDataAction; private Action StateAction; private Action SocketErrorAction; public string key { get; private set; } private string ip; private int port; private System.Threading.Timer timer = null; private static bool lock_connection = false; public void Connection(string ip, int port, Action ReceiveDataAction, Action SocketErrorAction, string key, Action StateAction) { if (Stop) return; if (lock_connection) return; if (key.Length != 16) throw new Exception("秘钥必须 == 16位!"); try { lock_connection = true; if (this.IsConnected) this.Close(); Console.WriteLine("连接中..."); this.ip = ip; this.port = port; this.ReceiveDataAction = ReceiveDataAction; this.StateAction = StateAction; this.SocketErrorAction = SocketErrorAction; this.key = key.Substring(0, 16); this.endPoint = new IPEndPoint(IPAddress.Parse(ip), port); lock (session_lock) { client = new AsyncTcpSession(); client.ReceiveBufferSize = 10 * 1024; client.DataReceived += Client_DataReceived; client.Connected += Client_Connected; client.Closed += Client_Closed; client.Error += Client_Error; client.Connect(endPoint); Thread.Sleep(500); if (!client.IsConnected) { client.Connect(endPoint); if (!client.IsConnected) throw new Exception("连接服务器失败,请检查是否填写正确!"); } } } catch (Exception ex) { if (WechatClient.IsLog) LogHelper.GetSingleObj().Info("断开", $"连接服务器失败:{ex.Message}"); StateAction?.Invoke($"连接服务器失败:{ex.Message} - {ex.StackTrace}"); } finally { lock_connection = false; } } private void Client_Closed(object sender, EventArgs e) { if (WechatClient.IsLog) LogHelper.GetSingleObj().Info("断开", $"与服务器{ip}连接断开!!"); StateAction?.Invoke($"与服务器{ip}连接断开!"); } private void Client_Connected(object sender, EventArgs e) { if (WechatClient.IsLog) LogHelper.GetSingleObj().Info("连接成功", $"与服务器{ip}连接成功!"); StateAction?.Invoke($"与服务器{ip}连接成功!"); } private long i = 0; private void timerCall(object state) { if (string.IsNullOrEmpty(ip) || string.IsNullOrEmpty(key) || port == 0) return; //throw new NotImplementedException(); try { if (Stop) { if (IsConnected) Close(); } if (!IsConnected) { if (Stop) StateAction?.Invoke($"您已断开与服务器{ip}失联!"); else { StateAction?.Invoke($"与服务器{ip}失联,重连中..."); if (WechatClient.IsLog) LogHelper.GetSingleObj().Info("失联", $"与服务器{ip}失联,重连中..."); Connection(ip, port, ReceiveDataAction, SocketErrorAction, key, StateAction); } } else { i++; //Console.WriteLine($"第{i}次测试,key={this.key}"); if (i == 1 || i % 5 == 0) { //Send(new BaseMsg() //{ // Cmd = PCRobotCMD.heartBreak, // RobotType = RobotType.客户端微信, // RobotUsername = "测试", // RobotUsernick = "测试-可以随时删除" //}); //Send(); //var wxs = WinForm.nms.ToList(); var robots = PCWechat.WechatClient.Users.Values.ToList(); foreach (var item in robots) { //var msg = new BaseMsg() //{ // Cmd = PCRobotCMD.heartBreak, // RobotType = RobotType.客户端系统, // RobotUsername = item.Wxid, // RobotUsernick = item.Nickname //}; if (item.HeartBreakTime.AddMinutes(6) > DateTime.Now) { var msg = new WechatStatus() { Cmd = item.Type == WechatType.Xiaoxie_QY ? PCRobotCMD.offline_workWeChat : PCRobotCMD.offline, RobotUsername = item.Wxid, RobotUsernick = item.Nickname, RobotType = item.Type == WechatType.Xiaoxie_QY ? RobotType.客户端企业微信 : RobotType.客户端微信, Status = Status.在线, Uin = item.Uin }; Send(msg); Thread.Sleep(50); } else { item.HeartBreakTime = DateTime.Now; Close(); if (!IsConnected) Connection(ip, port, ReceiveDataAction, SocketErrorAction, key, StateAction); } } } StateAction?.Invoke($"与服务器: {ip} 连接成功."); } } catch (Exception ex) { if (WechatClient.IsLog) LogHelper.GetSingleObj().Info("心跳包异常1", $"{ex.Message}"); StateAction?.Invoke($"心跳包异常: {ex.Message}"); } } private void Client_Error(object sender, ErrorEventArgs e) { if (SocketErrorAction != null) { if (WechatClient.IsLog) LogHelper.GetSingleObj().Info("Client_Error", $"{e.Exception.Message}"); SocketErrorAction(e.Exception); } } private void Client_DataReceived(object sender, DataEventArgs e) { byte[] new_data = new byte[e.Length]; Buffer.BlockCopy(e.Data, 0, new_data, 0, e.Length); var data = Encoding.UTF8.GetString(new_data); var json = HttpHelper.JsonToObject(data) as WechatStatus; if (json == null) { } else { //var client = WechatClient.Users.Values.ToList().FirstOrDefault(f => f.Wxid == json.RobotUsername && f.Type == (json.RobotType == RobotType.客户端企业微信 ? WechatType.Xiaoxie_QY : WechatType.Xiaoxie)); var client = WechatClient.Users.Values.ToList().FirstOrDefault(f => f.Wxid == json.RobotUsername); if (client != null) client.HeartBreakTime = DateTime.Now; return; } Console.WriteLine(Encoding.UTF8.GetString(new_data)); //ReceiveDataAction.BeginInvoke(Encoding.UTF8.GetString(new_data), null, null); ReceiveDataAction.BeginInvoke(data, null, null); } int retry = 0; private Thread threadConnection; public void Send(BaseMsg msg) { try { if (IsConnected) { try { //秘钥 //key = string.Empty; msg.Key = this.key; //Console.WriteLine("心跳测试:" + i + "," + msg.Key); var json = HttpHelper.ObjectToJson(msg); var data = PackTool.CompressString(json); // //if (!string.IsNullOrEmpty(key)) //{ // AESCryption aes = new AESCryption(); // data = aes.AesEncrypt(data, key); //} //data =HttpHelper.URLEncode(data); var send = msg.Cmd + " " + data + "\r\n"; var data_bytes = Encoding.UTF8.GetBytes(send); client.Send(data_bytes,0,data_bytes.Length); } catch (Exception ex) { StateAction?.Invoke($"发送消息失败: {ex.Message}"); } } else { StateAction?.Invoke($"发送消息失败: 没有与服务器建立连接!"); if (threadConnection == null || !threadConnection.IsAlive) { threadConnection = new Thread(new ThreadStart(delegate { try { Thread.Sleep(5000); if (!IsConnected) Connection(ip, port, ReceiveDataAction, SocketErrorAction, key, StateAction); } catch (Exception) { } })); threadConnection.IsBackground = true; threadConnection.Start(); } } } catch (Exception ex) { if (WechatClient.IsLog) LogHelper.GetSingleObj().Info("Send ERROR", $"{ex.Message}"); LogHelper.GetSingleObj().Error("Send ERROR:", $"{ex.Message} - {ex.StackTrace}"); } } } }