using CsharpHttpHelper; using PCRobot.Pack; using PCRobot.PCWechat; using PCRobot.Utils; using SuperSocket.ClientEngine; using SuperSocket.ProtoBase; using System; using System.Linq; using System.Net; using System.Text; using System.Text.RegularExpressions; using System.Threading; namespace PCRobot { public class EasySoc { #region 字段信息 static EasySoc _soc; public EasyClient client; public string key { get; private set; } string ip; int port; public bool Stop { get; set; } public bool IsConnected { get { return client != null && client.IsConnected; } } readonly static object session_lock = new object(); IPEndPoint endPoint; Action ReceiveDataAction; Action StateAction; Action SocketErrorAction; long i = 0; //Thread threadConnection; static bool lock_connection = false; #endregion public static EasySoc GetSocket() { if (_soc == null) _soc = new EasySoc(); return _soc; } private System.Threading.Timer timer = null; public EasySoc() { //timer = new Timer(new TimerCallback(timerCall), null, 0, 1000 * 5); var thread = new Thread(() => { while (true) { Thread.Sleep(1000 * 5); timerCall(null); } }); thread.IsBackground = true; thread.Start(); //FluentScheduler.JobManager.AddJob(heartBeat, t => //{ // t.WithName("心跳").ToRunNow().AndEvery(5).Seconds(); //}); } private void timerCall(object state) { if (string.IsNullOrEmpty(ip) || string.IsNullOrEmpty(key) || port == 0) return; //throw new NotImplementedException(); var sb = new StringBuilder(); try { sb.AppendLine("AAA"); if (Stop) { sb.AppendLine("BBB"); if (IsConnected) Close(); sb.AppendLine("ccc"); StateAction?.Invoke($"您已断开与服务器{ip}失联!"); return; } sb.AppendLine("DDD"); if (!IsConnected) { sb.AppendLine("EEE"); StateAction?.Invoke($"与服务器{ip}失联,重连中..."); if (WechatClient.IsLog) { sb.AppendLine("FFF"); LogHelper.GetSingleObj().Info("失联", $"与服务器{ip}失联,重连中..."); } Connection(ip, port, ReceiveDataAction, SocketErrorAction, key, StateAction); sb.AppendLine("GGG"); } else { sb.AppendLine("HHH"); i++; //Console.WriteLine($"第{i}次测试,key={this.key}"); if (i == 1 || i % 6 == 0) { sb.AppendLine("TTT"); Send(new CommonResult() { Cmd = PCRobotCMD.heartBreak, RobotType = RobotType.客户端系统, RobotUsername = string.Empty, RobotUsernick = "测试-nick", Data = Common.GetDevice() }); Thread.Sleep(50); sb.AppendLine("LLL"); var robots = WechatClient.Users.Values.ToList(); foreach (var item in robots) { sb.AppendLine("MMM"); 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,//Regex.Replace(item.Nickname, @"\s", "", RegexOptions.IgnoreCase), RobotType = item.Type == WechatType.Xiaoxie_QY ? RobotType.客户端企业微信 : RobotType.客户端微信, Status = Status.在线, Uin = item.Uin, Device = Common.GetDevice() }; Send(msg); Thread.Sleep(50); } else { sb.AppendLine("NNN"); item.HeartBreakTime = DateTime.Now; Close(); if (!IsConnected) Connection(ip, port, ReceiveDataAction, SocketErrorAction, key, StateAction); } } } sb.AppendLine("ZZZ"); StateAction?.Invoke($"与服务器: {ip} 连接成功."); } } catch (Exception ex) { if (WechatClient.IsLog) LogHelper.GetSingleObj().Info("心跳包异常1", $"{ex.Message}"); StateAction?.Invoke($"心跳包异常: {ex.Message} {ex.StackTrace} +{sb.ToString()}"); } } public void Send(BaseMsg msg) { try { if (IsConnected) { try { msg.Key = this.key; var json = HttpHelper.ObjectToJson(msg); var data = PackTool.CompressString(json); var send = msg.Cmd + " " + data + "\r\n"; var data_bytes = Encoding.UTF8.GetBytes(send); if (WechatClient.IsDebug) LogHelper.GetSingleObj().Debug("往服务器发送", $"{msg.Cmd} - {json} - {data.Length}"); //var senddata = new byte[_receiveBufferSize]; //for (int i = 0; i < data_bytes.Length; i++) //{ // senddata[i] = data_bytes[i]; //} client.Send(data_bytes); } catch (Exception ex) { StateAction?.Invoke($"发送消息失败: {ex.Message}"); } } } catch (Exception ex) { if (WechatClient.IsLog) LogHelper.GetSingleObj().Info("Send ERROR", $"{ex.Message}"); LogHelper.GetSingleObj().Error("Send ERROR:", $"{ex.Message} - {ex.StackTrace}"); } } private static int _receiveBufferSize = 1024 * 1024 * 10; 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; if (receiveDataAction != null) { this.ReceiveDataAction = receiveDataAction; } if (stateAction != null) { this.StateAction = stateAction; } if (socketErrorAction != null) { this.SocketErrorAction = socketErrorAction; } this.key = key.Substring(0, 16); this.endPoint = new IPEndPoint(IPAddress.Parse(ip), port); lock (session_lock) { client = new EasyClient(); client.Initialize(new MyReceiveFilter(), clientRcv); client.ReceiveBufferSize = _receiveBufferSize; //LogHelper.GetSingleObj().Info("", "client.ReceiveBufferSize = " + client.ReceiveBufferSize); //client.DataReceived += Client_DataReceived; client.Connected += Client_Connected; client.Closed += Client_Closed; client.Error += Client_Error; var rst = client.ConnectAsync(endPoint).Result; Thread.Sleep(500); if (!client.IsConnected) { rst = client.ConnectAsync(endPoint).Result; 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 clientRcv(StringPackageInfo obj) { if (WechatClient.IsDebug) LogHelper.GetSingleObj().Debug("", $"收到服务器消息:{obj.Key} - {obj.Body}"); if (obj.Key.ToLower().Trim().StartsWith("offline".ToLower())) { try { var json = HttpExtend.JsonToDictionary(obj.Body); if (json != null) { var client = WechatClient.Users.Values.ToList().FirstOrDefault(f => f.Wxid == json["RobotUsername"].ToString()); if (client != null) client.HeartBreakTime = DateTime.Now; } else { var text = PackTool.DecompressString(obj.Body); var json1 = HttpExtend.JsonToDictionary(text); if (json1 != null) { var client = WechatClient.Users.Values.ToList().FirstOrDefault(f => f.Wxid == json1["RobotUsername"].ToString()); if (client != null) client.HeartBreakTime = DateTime.Now; } } } catch (Exception ex) { } return; } //Console.WriteLine(obj.Body); //ReceiveDataAction.BeginInvoke(Encoding.UTF8.GetString(new_data), null, null); ReceiveDataAction.BeginInvoke(obj.Key, obj.Body, null, null); } public void Close(bool isQuit = false) { try { lock (session_lock) { if (client != null) { if (isQuit) { FluentScheduler.JobManager.RemoveJob("心跳"); } //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}"); } } 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_Closed(object sender, EventArgs e) { if (WechatClient.IsLog) LogHelper.GetSingleObj().Info("断开", $"与服务器{ip},{e} - 连接断开!!"); StateAction?.Invoke($"与服务器{ip}连接断开!"); } private void Client_Connected(object sender, EventArgs e) { if (WechatClient.IsLog) { LogHelper.GetSingleObj().Info("连接成功", $"与服务器{ip}连接成功!"); } StateAction?.Invoke($"与服务器{ip}连接成功!"); } } }