Files
ClientServerProject/软件系统服务端模版/Form1.cs
2017-06-07 16:59:17 +08:00

930 lines
41 KiB
C#
Raw 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 System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using HslCommunication.Enthernet;
using System.Threading;
using CommonLibrary;
using Newtonsoft.Json.Linq;
using HslCommunication.BasicFramework;
/******************************************************************************************
*
* 模版日期 2017-05-30
* 创建人 Richard.Hu
* 版权所有 Richard.Hu
* 授权说明 模版仅授权个人使用如需商用请联系hsl200909@163.com洽谈
* 说明 JSON组件引用自james newton-king遵循MIT授权协议
* 网络组件 网络组件的版权由Richard.Hu所有
*
********************************************************************************************/
/******************************************************************************************
*
* 注意:本代码的相关操作未作密码验证,如有需要,请自行完成
* 示例具体示例参照本页面Form1_FormClosing(object sender, FormClosingEventArgs e)方法
*
********************************************************************************************/
/******************************************************************************************
*
* 本项目模版不包含 《软件自动更新.exe》
* 如需支持部署环境的自动升级 请联系hsl200909@163.com获取
* 软件自动更新.exe 将绑定IP端口和软件名称后授权销售30元人民币一组永久使用
*
********************************************************************************************/
namespace
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
#region +
/// <summary>
/// 指示窗口是否处于显示中
/// </summary>
private bool IsWindowShow { get; set; } = false;
/// <summary>
/// 指示系统是否启动
/// </summary>
private bool IsSystemStart { get; set; } = false;
private void Form1_Load(object sender, EventArgs e)
{
//初始化日志工具
RuntimeLogHelper = new SoftLogHelper()
{
LogSaveFileName = Application.StartupPath + @"\log.txt",
};
//初始化反馈信息工具
AdviceLogHelper = new SoftLogHelper()
{
LogSaveFileName = Application.StartupPath + @"\advice_log.txt",
};
//保存路径初始化
UserServer.ServerSettings.FileSavePath = Application.StartupPath + @"\settings.txt";
//加载参数
UserServer.ServerSettings.LoadByFile();
toolStripStatusLabel_version.Text = UserServer.ServerSettings.SystemVersion.ToString();
toolStripStatusLabel1.Text = $"本软件著作权归{Resource.StringResouce.SoftCopyRight}所有";
//加载账户信息
UserServer.ServerAccounts.FileSavePath = Application.StartupPath + @"\accounts.txt";
UserServer.ServerAccounts.LoadByFile();
UserServer.ServerAccounts.LogHelper = RuntimeLogHelper;
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
//密码验证的示例,此处关闭窗口验证
using (FormPasswordCheck fpc = new FormPasswordCheck("123456"))
{
if (fpc.ShowDialog() == DialogResult.OK)
{
IsWindowShow = false;
Thread.Sleep(20);
//关闭网络引擎
net_socket_server.ServerClose();
net_simplify_server.ServerClose();
net_udp_server.ServerClose();
}
else
{
//取消关闭
e.Cancel = true;
}
}
//紧急数据的保存已经放置到dispose方法中即时发生BUG或直接关机也能存储数据
}
private void Form1_Shown(object sender, EventArgs e)
{
IsWindowShow = true;
//维护初始化
MaintenanceInitialization();
//时间引擎初始化
TimeTickInitilization();
Refresh();
ToolStripMenuItem.PerformClick();
}
#endregion
#region
private void ToolStripMenuItem_Click(object sender, EventArgs e)
{
if (!IsSystemStart)
{
Net_Simplify_Server_Initialization();//同步网络初始化
Net_Socket_Server_Initialization();//异步网络初始化
Net_SoftUpdate_Server_Initialization();//软件更新引擎初始化
Net_File_Update_Initialization();//软件异地更新引擎初始化
Simple_File_Initiaization();//共享文件引擎初始化
Net_Udp_Server_Initialization();//UDP引擎服务初始化
ToolStripMenuItem.Text = "已启动";
ToolStripMenuItem.BackColor = Color.LimeGreen;
IsSystemStart = true;
}
}
private void ToolStripMenuItem_Click(object sender, EventArgs e)
{
using (FormVersionControl fvc = new FormVersionControl(UserServer.ServerSettings))
{
fvc.ShowDialog();
toolStripStatusLabel_version.Text = UserServer.ServerSettings.SystemVersion.ToString();
}
}
private void ToolStripMenuItem_Click(object sender, EventArgs e)
{
using (FormMaintenance fm = new FormMaintenance(UserServer.ServerSettings))
{
fm.ShowDialog();
MaintenanceInitialization();
}
}
private void ToolStripMenuItem_Click(object sender, EventArgs e)
{
//测试发送字节数据
//net_socket_server.SendAllClients(BitConverter.GetBytes(12345678));
//将消息群发给所有的客户端,并使用消息弹窗的方式显示
using (FormInputAndAction fiaa = new FormInputAndAction(
m =>
{
net_socket_server.SendAllClients(CommonHeadCode.MultiNetHeadCode. + m); return true;
}))
{
fiaa.ShowDialog();
}
}
private void ToolStripMenuItem_Click(object sender, EventArgs e)
{
//关闭信号发送至所有在线客户端
net_socket_server.SendAllClients(CommonHeadCode.MultiNetHeadCode.);
}
private void ToolStripMenuItem_Click(object sender, EventArgs e)
{
using (FormAbout fm = new FormAbout(
Resource.StringResouce.SoftName, UserServer.ServerSettings.SystemVersion,
2017, Resource.StringResouce.SoftCopyRight))
{
fm.ShowDialog();
}
}
private void ToolStripMenuItem_Click(object sender, EventArgs e)
{
using (FormAuthorAdvertisement faa = new FormAuthorAdvertisement())
{
faa.ShowDialog();
}
}
private void ToolStripMenuItem_Click(object sender, EventArgs e)
{
//该部分比较复杂,需要对委托,匿名委托概念比较清晰
using (FormAccountManage fam = new FormAccountManage(() => UserServer.ServerAccounts.GetAllAccountsJson(),
m => { UserServer.ServerAccounts.LoadAllAccountsJson(m); return true; }))
{
fam.ShowDialog();
}
}
private void ToolStripMenuItem_Click(object sender, EventArgs e)
{
using (FormAboutVersion fav = new FormAboutVersion(UserServer.ServerSettings.SystemVersion))
{
fav.ShowDialog();
}
}
private void MaintenanceInitialization()
{
//维护状态变更
if (UserServer.ServerSettings.Can_Account_Login)
{
label3.Text = "可登录";
label3.BackColor = Color.LimeGreen;
}
else
{
label3.Text = "维护中";
label3.BackColor = Color.Tomato;
}
}
#endregion
#region
/// <summary>
/// 支持软件自动更新的后台服务引擎
/// </summary>
private Net_SoftUpdate_Server net_soft_update_Server = new Net_SoftUpdate_Server();
private void Net_SoftUpdate_Server_Initialization()
{
try
{
net_soft_update_Server.LogHelper.LogSaveFileName = Application.StartupPath + @"\update_log.txt";
//在服务器的这个路径下放置客户端运行的所有文件不要包含settings文件不要从此处运行
//只放置exe和dll组件必须放置软件自动更新.exe
net_soft_update_Server.KeyToken = CommonHeadCode.KeyToken;
net_soft_update_Server.FileUpdatePath = Application.StartupPath + @"\ClientFiles";//客户端文件路径
net_soft_update_Server.ServerStart(CommonLibrary.CommonLibrary.Port_Update_Net);
}
catch (Exception ex)
{
SoftBasic.ShowExceptionMessage(ex);
}
}
#endregion
#region
/// <summary>
/// 用于局域网异地更新服务器的客户端程序的引擎,仅限客户端
/// </summary>
private Net_File_Server net_file_update = new Net_File_Server();
/// <summary>
/// 软件异地更新的初始化,如不需要可以不启动,该功能支持发送客户端文件至服务器实现覆盖更新
/// </summary>
private void Net_File_Update_Initialization()
{
try
{
net_file_update.FilesPath = Application.StartupPath + @"\ClientFiles";//服务器客户端需要更新的路径,与上述一致
net_file_update.LogHelper.LogSaveFileName = Application.StartupPath + @"\update_file_log.txt";
net_file_update.KeyToken = CommonHeadCode.KeyToken;
net_file_update.ServerStart(CommonLibrary.CommonLibrary.Port_Update_Remote);
}
catch (Exception ex)
{
SoftBasic.ShowExceptionMessage(ex);
}
}
#endregion
#region
/// <summary>
/// 用户同步数据传送的引擎
/// </summary>
private Net_Simplify_Server net_simplify_server = new Net_Simplify_Server();
/// <summary>
/// 同步传送数据的初始化
/// </summary>
private void Net_Simplify_Server_Initialization()
{
try
{
net_simplify_server.KeyToken = CommonHeadCode.KeyToken;//设置身份令牌
net_simplify_server.LogHelper.LogSaveFileName = Application.StartupPath + @"\simplify_log.txt";//日志路径
net_simplify_server.ReceiveStringEvent += Net_simplify_server_ReceiveStringEvent;//接收到字符串触发
net_simplify_server.ReceivedBytesEvent += Net_simplify_server_ReceivedBytesEvent;//接收到字节触发
net_simplify_server.ServerStart(CommonLibrary.CommonLibrary.Port_Second_Net);
}
catch (Exception ex)
{
SoftBasic.ShowExceptionMessage(ex);
}
}
/// <summary>
/// 接收来自客户端的字节数据
/// </summary>
/// <param name="object1">客户端的地址</param>
/// <param name="object2">字节数据,根据实际情况选择是否使用</param>
private void Net_simplify_server_ReceivedBytesEvent(AsyncStateBase object1, byte[] object2)
{
net_simplify_server.SendMessage(object1, object2);
}
/// <summary>
/// 接收到来自客户端的数据,此处需要放置维护验证,更新验证等等操作
/// </summary>
/// <param name="object1">客户端的地址</param>
/// <param name="object2">消息数据,应该使用指令头+数据组成</param>
private void Net_simplify_server_ReceiveStringEvent(AsyncStateBase object1, string object2)
{
//必须返回结果调用SendMessage(object1,[实际数据]);
if (object2.StartsWith("A"))
{
DataProcessingWithStartA(object1, object2);
}
else if (object2.StartsWith("B"))
{
DataProcessingWithStartB(object1, object2);
}
else
{
net_simplify_server.SendMessage(object1, object2);
}
}
/****************************************************************************************************
*
*
* 数据处理中心,同步信息中的所有的细节处理均要到此处来处理
*
*
****************************************************************************************************/
/// <summary>
/// A指令块处理系统基础运行的消息
/// </summary>
/// <param name="object1">网络状态对象</param>
/// <param name="object2">实际的数据</param>
private void DataProcessingWithStartA(AsyncStateBase object1, string object2)
{
string headCode = object2.Substring(0, 4);
if (headCode == CommonHeadCode.SimplifyHeadCode.)
{
net_simplify_server.SendMessage(object1, UserServer.ServerSettings.Can_Account_Login ? "1" : "0" +
UserServer.ServerSettings.Account_Forbidden_Reason);
}
else if (headCode == CommonHeadCode.SimplifyHeadCode.)
{
net_simplify_server.SendMessage(object1, UserServer.ServerSettings.SystemVersion.ToString());
}
else if (headCode == CommonHeadCode.SimplifyHeadCode.)
{
Newtonsoft.Json.Linq.JObject json = new Newtonsoft.Json.Linq.JObject();
json.Add(nameof(UserServer.ServerSettings.Announcement), new Newtonsoft.Json.Linq.JValue(UserServer.ServerSettings.Announcement));
net_simplify_server.SendMessage(object1, json.ToString());
}
else if (headCode == CommonHeadCode.SimplifyHeadCode.)
{
//此处使用的是组件自带的验证的方式如果使用SQL数据库另行验证
JObject json = JObject.Parse(object2.Substring(4));
//提取账户,密码
string name = SoftBasic.GetValueFromJsonObject(json, UserAccount.UserNameText, "");
string password = SoftBasic.GetValueFromJsonObject(json, UserAccount.PasswordText, "");
net_simplify_server.SendMessage(object1, UserServer.ServerAccounts.CheckAccountJson(
name, password, object1.GetRemoteEndPoint().Address.ToString()));
}
else if (headCode == CommonHeadCode.SimplifyHeadCode.)
{
UserServer.ServerSettings.Announcement = object2.Substring(4);
//通知所有客户端更新公告
net_socket_server.SendAllClients(object2);
net_simplify_server.SendMessage(object1, "成功");
}
else if (headCode == CommonHeadCode.SimplifyHeadCode.)
{
//返回服务器的账户信息
net_simplify_server.SendMessage(object1, UserServer.ServerAccounts.GetAllAccountsJson());
}
else if (headCode == CommonHeadCode.SimplifyHeadCode.)
{
//更新服务器的账户信息
UserServer.ServerAccounts.LoadAllAccountsJson(object2.Substring(4));
net_simplify_server.SendMessage(object1, "成功");
}
else if (headCode == CommonHeadCode.SimplifyHeadCode.)
{
//更新服务器的账户密码此处使用的是组件自带的验证的方式如果使用SQL数据库另行验证
JObject json = JObject.Parse(object2.Substring(4));
//提取账户,密码
string name = SoftBasic.GetValueFromJsonObject(json, UserAccount.UserNameText, "");
string password = SoftBasic.GetValueFromJsonObject(json, UserAccount.PasswordText, "");
UserServer.ServerAccounts.UpdatePassword(name, password);
net_simplify_server.SendMessage(object1, "成功");
}
else if (headCode == CommonHeadCode.SimplifyHeadCode.)
{
try
{
UserServer.ServerSettings.SystemVersion = new SystemVersion(object2.Substring(4));
UserServer.ServerSettings.SaveToFile();
toolStripStatusLabel_version.Text = UserServer.ServerSettings.SystemVersion.ToString();
net_simplify_server.SendMessage(object1, "1");
}
catch
{
net_simplify_server.SendMessage(object1, "0");
}
}
else if (headCode == CommonHeadCode.SimplifyHeadCode.)
{
bool result = UserServer.ServerAccounts.AddNewAccount(object2.Substring(4));
net_simplify_server.SendMessage(object1, result ? "1" : "0");
}
else if (headCode == CommonHeadCode.SimplifyHeadCode.)
{
net_simplify_server.SendMessage(object1, net_simple_file_server.ToJsonString());
}
else if (headCode == CommonHeadCode.SimplifyHeadCode.)
{
AdviceLogHelper.SaveInformation(object2.Substring(4));
net_simplify_server.SendMessage(object1, "成功");
}
else
{
net_simplify_server.SendMessage(object1, object2);
}
}
/// <summary>
/// B指令块处理日志相关的消息
/// </summary>
/// <param name="object1"></param>
/// <param name="object2"></param>
private void DataProcessingWithStartB(AsyncStateBase object1, string object2)
{
string headCode = object2.Substring(0, 4);
if (headCode == CommonHeadCode.SimplifyHeadCode.)
{
net_simplify_server.SendMessage(object1, net_socket_server.LogHelper.GetLogText());
RuntimeLogHelper.SaveInformation("网络日志查看");
}
else if (headCode == CommonHeadCode.SimplifyHeadCode.)
{
net_socket_server.LogHelper.ClearLogText();
net_simplify_server.SendMessage(object1, "成功");
RuntimeLogHelper.SaveWarnning("网络日志清空");
}
else if (headCode == CommonHeadCode.SimplifyHeadCode.)
{
net_simplify_server.SendMessage(object1, net_simplify_server.LogHelper.GetLogText());
RuntimeLogHelper.SaveInformation("同步日志查看");
}
else if (headCode == CommonHeadCode.SimplifyHeadCode.)
{
net_simplify_server.LogHelper.ClearLogText();
net_simplify_server.SendMessage(object1, "成功");
RuntimeLogHelper.SaveWarnning("同步日志清空");
}
else if (headCode == CommonHeadCode.SimplifyHeadCode.)
{
net_simplify_server.SendMessage(object1, net_soft_update_Server.LogHelper.GetLogText());
RuntimeLogHelper.SaveInformation("更新日志查看");
}
else if (headCode == CommonHeadCode.SimplifyHeadCode.)
{
net_soft_update_Server.LogHelper.ClearLogText();
net_simplify_server.SendMessage(object1, "成功");
RuntimeLogHelper.SaveWarnning("更新日志清空");
}
else if (headCode == CommonHeadCode.SimplifyHeadCode.)
{
net_simplify_server.SendMessage(object1, RuntimeLogHelper.GetLogText());
RuntimeLogHelper.SaveInformation("运行日志查看");
}
else if (headCode == CommonHeadCode.SimplifyHeadCode.)
{
RuntimeLogHelper.ClearLogText();
net_simplify_server.SendMessage(object1, "成功");
RuntimeLogHelper.SaveInformation("运行日志清空");
}
else if (headCode == CommonHeadCode.SimplifyHeadCode.)
{
net_simplify_server.SendMessage(object1, net_simple_file_server.LogHelper.GetLogText());
RuntimeLogHelper.SaveInformation("共享文件日志查看");
}
else if (headCode == CommonHeadCode.SimplifyHeadCode.)
{
net_simple_file_server.LogHelper.ClearLogText();
net_simplify_server.SendMessage(object1, "成功");
RuntimeLogHelper.SaveInformation("共享文件日志清空");
}
else if (headCode == CommonHeadCode.SimplifyHeadCode.)
{
net_simplify_server.SendMessage(object1, AdviceLogHelper.GetLogText());
RuntimeLogHelper.SaveInformation("建议反馈日志查看");
}
else if (headCode == CommonHeadCode.SimplifyHeadCode.)
{
AdviceLogHelper.ClearLogText();
net_simplify_server.SendMessage(object1, "成功");
RuntimeLogHelper.SaveWarnning("建议反馈日志清空");
}
else if (headCode == CommonHeadCode.SimplifyHeadCode.UDP日志查看)
{
net_simplify_server.SendMessage(object1, net_udp_server.LogHelper.GetLogText());
RuntimeLogHelper.SaveInformation("UDP日志查看");
}
else if (headCode == CommonHeadCode.SimplifyHeadCode.UDP日志清空)
{
net_udp_server.LogHelper.ClearLogText();
net_simplify_server.SendMessage(object1, "成功");
RuntimeLogHelper.SaveWarnning("UDP日志清空");
}
else
{
net_simplify_server.SendMessage(object1, object2);
}
}
/****************************************************************************************************
*
*
* 您在下面可以自己扩展数据处理的方法,设计原则为运行速度尽可能的快,不要长时间阻塞
*
*
****************************************************************************************************/
#endregion
#region
/// <summary>
/// 异步客户端管理引擎,维护所有的客户端在线情况,支持主动发数据到所有的客户端
/// </summary>
private Net_Socket_Server net_socket_server = new Net_Socket_Server();
/// <summary>
/// 异步传送数据的初始化
/// </summary>
private void Net_Socket_Server_Initialization()
{
try
{
net_socket_server.KeyToken = CommonHeadCode.KeyToken;//设置身份令牌
net_socket_server.LogHelper.LogSaveFileName = Application.StartupPath + @"\net_log.txt";
net_socket_server.FormatClientOnline = "#IP:{0} Name:{1}";//必须为#开头,具体格式可由自身需求确定
net_socket_server.IsSaveLogClientLineChange = true;//设置客户端上下线是否记录到日志
net_socket_server.ClientOnline += Net_socket_server_ClientOnline;//客户端上线触发
net_socket_server.ClientOffline += Net_socket_server_ClientOffline;//客户端下线触发,包括异常掉线
net_socket_server.MessageAlerts += Net_socket_server_MessageAlerts;//服务器产生提示消息触发
net_socket_server.AcceptByte += Net_socket_server_AcceptByte;//服务器接收到字节数据触发
net_socket_server.AcceptString += Net_socket_server_AcceptString;//服务器接收到字符串数据触发
net_socket_server.ServerStart(CommonLibrary.CommonLibrary.Port_Main_Net);
}
catch (Exception ex)
{
SoftBasic.ShowExceptionMessage(ex);
}
}
private void Net_socket_server_AcceptString(AsyncStateOne object1, string object2)
{
//如果此处充斥大量if语句影响观感则考虑进行指令头分类操作客户端异步发送的字符串都会到此处处理
if (object2.StartsWith("H"))
{
//H类系统指令
DataProcessingWithStartH(object1, object2);
}
}
/// <summary>
/// H开头的处理块
/// </summary>
/// <param name="object1"></param>
/// <param name="headcode">指令头</param>
/// <param name="object2"></param>
private void DataProcessingWithStartH(AsyncStateOne object1, string object2)
{
string headCode = object2.Substring(0, 4);
if (headCode == CommonHeadCode.MultiNetHeadCode.)
{
string content = headCode + object1.LoginAlias + DateTime.Now.ToString(" yyyy-MM-dd HH:mm:ss") + Environment.NewLine + object2.Substring(4);
//转发所有的客户端,包括发送者
net_socket_server.SendAllClients(content);
}
}
private void Net_socket_server_AcceptByte(AsyncStateOne object1, byte[] object2)
{
//如果此处充斥大量if语句影响观感则考虑进行指令头分类操作客户端异步发送的字节数组都会到此处处理
}
private void Net_socket_server_MessageAlerts(string object1)
{
//同上的方法,此处处理数据时处于后台线程
if (IsWindowShow && IsHandleCreated)
{
BeginInvoke(new Action(() =>
{
textBox1.AppendText(object1 + Environment.NewLine);
}));
}
}
private void Net_socket_server_ClientOffline(AsyncStateOne object1, string object2)
{
Net_socket_clients_change(DateTime.Now.ToString("MM-dd HH:mm:ss ") + object1._IpEnd_Point.Address.ToString() + "" +
object1.LoginAlias + " " + object2);
}
private void Net_socket_server_ClientOnline(AsyncStateOne object1)
{
//上线后回发一条数据初始化信息
JObject json = new JObject
{
{ "Time", new JValue(DateTime.Now) },
{ "FileCount", new JValue(net_simple_file_server.File_Count()) }
};
net_socket_server.Send(object1, CommonHeadCode.MultiNetHeadCode. + json.ToString());
//此处决定要不要将在线客户端的数据发送所有客户端
net_socket_server.SendAllClients(CommonHeadCode.MultiNetHeadCode.线 + net_socket_server.AllClients);
//触发上下线功能
Net_socket_clients_change(DateTime.Now.ToString("MM-dd HH:mm:ss ") + object1._IpEnd_Point.Address.ToString() + "" +
object1.LoginAlias + " 上线");
}
private void Net_socket_clients_change(string str)
{
if (IsWindowShow && IsHandleCreated)
{
BeginInvoke(new Action(() =>
{
textBox1.AppendText(str + Environment.NewLine);
listBox1.DataSource = net_socket_server.AllClients.Split('#');
label4.Text = net_socket_server.ClientCount.ToString();
}));
}
}
#endregion
#region 线
/*********************************************************************************************
*
* 说明 一个后台线程,用来执行一些周期执行的东西
* 注意 它不仅执行每秒触发的代码,也支持每分钟,每天,每月,每年等等
*
********************************************************************************************/
/// <summary>
/// 初始化后台的计数线程
/// </summary>
public void TimeTickInitilization()
{
toolStripStatusLabel_time.Alignment = ToolStripItemAlignment.Right;
statusStrip1.LayoutStyle = ToolStripLayoutStyle.StackWithOverflow;
toolStripStatusLabel_time.ForeColor = Color.Purple;//紫色
Thread thread = new Thread(new ThreadStart(ThreadTimeTick));
thread.IsBackground = true;
thread.Start();
}
public void ThreadTimeTick()
{
Thread.Sleep(300);//加一个微小的延时
int second = DateTime.Now.Second - 1;
int minute = -1;
int hour = -1;
int day = -1;
Action DTimeShow = delegate
{
toolStripStatusLabel_time.Text = DateTime.Now.ToString();
};
while (IsWindowShow)
{
while (DateTime.Now.Second == second)
{
Thread.Sleep(20);
}
second = DateTime.Now.Second;
if (IsWindowShow && IsHandleCreated) Invoke(DTimeShow);
//每隔一分钟将时间发送给所有客户端,格式为标准时间
if (second == 0)
{
net_socket_server.SendAllClients(CommonHeadCode.MultiNetHeadCode. +
DateTime.Now.ToString("O"));
}
if (minute != DateTime.Now.Minute)
{
minute = DateTime.Now.Minute;
//每分钟执行的代码
}
if (hour != DateTime.Now.Hour)
{
hour = DateTime.Now.Hour;
//每小时执行的代码
}
if (day != DateTime.Now.Day)
{
day = DateTime.Now.Day;
//每天执行的代码
}
}
}
#endregion
#region
/// <summary>
/// 共享文件服务器引擎
/// </summary>
private SimpleShareFileServer net_simple_file_server { get; set; } = null;
/// <summary>
/// 共享文件服务引擎初始化
/// </summary>
private void Simple_File_Initiaization()
{
try
{
net_simple_file_server = new SimpleShareFileServer()
{
//文件信息存储路径
FileSavePath = Application.StartupPath + @"\files.txt"
};
net_simple_file_server.ReadFromFile();
net_simple_file_server.LogHelper.LogSaveFileName = Application.StartupPath + @"\share_file_log.txt";
//文件存储路径
net_simple_file_server.File_save_path = Application.StartupPath + @"\Files";
net_simple_file_server.FileChange += Net_simple_file_server_FileChange;
net_simple_file_server.ServerStart(CommonLibrary.CommonLibrary.Port_Share_File);
}
catch (Exception ex)
{
SoftBasic.ShowExceptionMessage(ex);
}
}
private void Net_simple_file_server_FileChange()
{
//将文件数据发送给客户端
net_socket_server.SendAllClients(CommonHeadCode.MultiNetHeadCode. + net_simple_file_server.File_Count());
}
#endregion
#region
/**********************************************************************************************************
*
* 说明: 用来记录意见反馈的数据
* 举例: AdviceLogHelper.SaveInformation("张三:主界面的颜色稍微调整一下");
*
**********************************************************************************************************/
/// <summary>
/// 用来记录一般的事物日志
/// </summary>
private SoftLogHelper AdviceLogHelper { get; set; }
#endregion
#region Udp网络通信块
/*********************************************************************************************************
*
* 说明 一个用于网络间通信的UDP服务引擎客户端调用UserClient.Net_Udp_Client.SendMessage(data);发送
* 详细请参考客户端FormMainWindow中的udp发送说明
* 特点 该Udp引擎非常健壮接收失败了会抛弃本次接收自动进入下一轮接收。
* 安全 本引擎含有数据长度校验机制,确保服务器接收到的数据是正确的,没有丢失的
* 注意 如果服务器配置了ReceiveCacheLength = 1024那么客户端发送的字符串数据长度不能超过1000否则服务器会自动丢弃可在日志中查看
* 警告 如果想要你自己的软件支持向本引擎访问,必须使用该网络组件实现,参考客户端定义,否则发送失败
*
**********************************************************************************************************/
/// <summary>
/// 服务器的UDP核心引擎
/// </summary>
private UdpNetServer net_udp_server { get; set; }
private void Net_Udp_Server_Initialization()
{
try
{
net_udp_server = new UdpNetServer();
net_udp_server.LogHelper.LogSaveFileName = Application.StartupPath + @"\udp_log.txt";//日志路径
net_udp_server.ReceiveCacheLength = 1024;//单次接收数据的缓冲长度
net_udp_server.AcceptByte += Net_udp_server_AcceptByte;//接收到字节数据的时候触发事件
net_udp_server.AcceptString += Net_udp_server_AcceptString;//接收到字符串数据的时候触发事件
net_udp_server.ServerStart(CommonLibrary.CommonLibrary.Port_Udp_Server);
}
catch(Exception ex)
{
SoftBasic.ShowExceptionMessage(ex);
}
}
private void Net_udp_server_AcceptString(AsyncStateOne object1, string object2)
{
//此处为测试
Invoke(new Action(() =>
{
textBox1.AppendText($"{DateTime.Now.ToString("MM-dd HH:mm:ss ")}来自IP:{object1._IpEnd_Point.Address.ToString()} 内容:{object2}{Environment.NewLine}");
}));
}
private void Net_udp_server_AcceptByte(AsyncStateOne object1, byte[] object2)
{
//具体用法参考上面字符串方法
}
#endregion
#region 访PLC块示例代码
/*************************************************************************************************
*
* 以下展示一个高性能访问多台PLC数据的类即使同时访问100台设备性能也是非常高
*
* 该类没有仔细的在现场环境测试过,不保证完全可用
*
*************************************************************************************************/
HslCommunication.Profinet.MelsecNetMultiAsync MelsecMulti { get; set; }
private void MelsecNetMultiInnitialization()
{
List<System.Net.IPAddress> IpEndPoints = new List<System.Net.IPAddress>();
//增加100台需要访问的三菱设备指定所有设备IP和端口注意顺序很重要
for (int i = 1; i < 100; i++)
{
IpEndPoints.Add(System.Net.IPAddress.Parse("192.168.10." + i));
}
//每隔1秒钟访问一次读取的地址为D6000-D6019超时时间为700毫秒主端口为6000备用端口为6001
MelsecMulti = new HslCommunication.Profinet.MelsecNetMultiAsync(0, 0, HslCommunication.Profinet.MelsecDataType.D, 6000, 20, 700, 1000, IpEndPoints.ToArray(), 6000, 6001);
MelsecMulti.OnReceivedData += MelsecMulti_OnReceivedData;//所有机台的数据都返回时触发
}
private void MelsecMulti_OnReceivedData(byte[] object1)
{
/*********************************************************************************************
*
* 正常情况下一秒触发一次object1包含了所有机台读取到的数据
* 比如每台设备读取D6000开始20个D如上述指令所示
* 那么每台设备数据长度为20*2+2=42个byte100台设备就是4200字节长度
* 也就是说object1的0-41字节是第一台设备的以此类推
* 每台设备的前两个字节都为0才说明本次数据访问正常为0x00,0x01说明连接失败其他说明说明三菱本身的异常
*
********************************************************************************************/
for (int i = 0; i < 100; i++)
{
int startIndex = i * 42;
ushort netState = BitConverter.ToUInt16(object1, startIndex);//为0说明数据正常不为0说明网络访问失败或是指令出错
}
}
#endregion
#region
private SoftNumericalOrder OrderAutoCreate { get; set; }
/// <summary>
/// 流水号初始化方法如果需要可以放到窗口的load方法中
/// </summary>
private void OrderInitialization()
{
/*********************************************************************************************************
*
* 说明 此处的时间格式是年月日7是指跟在时间后面的序号的位数不够补零
* 示例1 调用 string str = OrderAutoCreate.GetNumericalOrder();//str为 AB201705190000001
* 示例2 调用 string str = OrderAutoCreate.GetNumericalOrder("KN");//str为 KN201705190000002
* 注意 默认计数不清空后面的12会一值累加可以调用900亿亿次如果需要定期清空请自行周期调用OrderAutoCreate.ClearNumericalOrder();
* 提示 如果需要定期清空在本页面的ThreadTimeTick()方法中清空即可
* 性能 一秒钟可以响应请求100万次并成功存储当前计数值
*
**********************************************************************************************************/
OrderAutoCreate = new SoftNumericalOrder("AB", "yyyyMMdd", 7, Application.StartupPath + @"\order.txt");
}
#endregion
/*********************************************************************************************************
*
* 说明 日志的使用方式分为4个等级1.普通 2.信息 3.警告 4.错误 对应的调用方法不一致
* 具体 如果想要调用存储[信息]等级日志,调用 RuntimeLogHelper.SaveInformation("等待存储的信息")
* 大小 调用10000次存储信息后日志文件大小在200K左右需要手动进行情况日志
* 注意 在存储信息时不要带有'['和']'这两个字符,会影响日志筛选时的准确性
*
**********************************************************************************************************/
/// <summary>
/// 用来记录一般的事物日志
/// </summary>
private SoftLogHelper RuntimeLogHelper { get; set; }
}
}