old_flsystem/PCRobot/EasySoc.cs

326 lines
12 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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<string> ReceiveDataAction;
private Action<string> StateAction;
private Action<Exception> 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<string> ReceiveDataAction, Action<Exception> SocketErrorAction, string key, Action<string> 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<WechatStatus>(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}");
}
}
}
}