Files
lserp_cs_6.0/其他程序/ServerNotice/Service.cs
T
cyf ab56a9bcf7 基线 SVN r240
SVN-Revision: r240
2025-02-06 06:46:06 +00:00

380 lines
16 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 Lskj.Business;
using Lskj.Business.Impl;
using Lskj.Core;
using Lskj.Model;
using Lskj.Util;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.ServiceProcess;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace ServerNotice
{
public partial class Service : ServiceBase
{
public Service()
{
InitializeComponent();
}
private Thread mainThread;
public System.Timers.Timer Timer = new System.Timers.Timer();
public System.Timers.Timer timer = new System.Timers.Timer();
///
public string DataAddress = string.Empty;
public string DataName = string.Empty;
public string Port = string.Empty;
///获取本地的IP地址
public string AddressIP = string.Empty;
/// <summary>
/// 旧的数据源存储
/// </summary>
public DataTable oldData = new DataTable();
Socket sck = null;
//Thread thread = null;
/// <summary>
/// 初始化界面的本机ip地址值和端口
/// </summary>
private void IniControl()
{
try
{
foreach (IPAddress _IPAddress in Dns.GetHostEntry(Dns.GetHostName()).AddressList)
{
if (_IPAddress.AddressFamily.ToString() == "InterNetwork")
{
//AddressIP = "192.168.0.240";
AddressIP = _IPAddress.ToString();
string dataAddre = IniHelper.Read("MenuConfig.ini", "MenuConfig", string.Format("Server_{0}", AddressIP));
string[] dataAddress = dataAddre.Split('^');
if (dataAddress.Length == 3)
{
DataAddress = dataAddress[0];
DataName = dataAddress[1];
Port = dataAddress[2];
WriteLog(DataAddress + "_" + DataName);
break;
}
}
}
}
catch (Exception ex)
{
WriteLog("错误信息:" + ex.Message);
}
}
//点击开启服务端监听
//private void btn_StarServer_Click(object sender, EventArgs e)
//{
// LoadStartServer();
//}
/// <summary>
/// 建立soket数据方法
/// </summary>
public void LoadStartServer()
{
try
{
DBConfig.Instance.ServerName = DataAddress;
DBConfig.Instance.DataBase = DataName;
if (DBConfig.Instance.CreateConnection())
{
//创建一个Socket实例
//第一个参数表示使用ipv4
//第二个参数表示发送的是数据流
//第三个参数表示使用的协议是Tcp协议
sck = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
//获取ip地址
IPAddress ip = IPAddress.Parse(AddressIP);
//创建一个网络通信节点,这个通信节点包含了ip地址,跟端口号。
//这里的端口我们设置为1029,这里设置大于1024,为什么自己查一下端口号范围使用说明。
IPEndPoint endpoint = new IPEndPoint(ip, Convert.ToInt32(string.IsNullOrEmpty(Port) ? "8080" : Port));//创建一个网络通信节点,该节点中包含了IP地址和端口号.
//this.portBox.Text = endpoint.ToString();
//Socket绑定网路通信节点
WriteLog("端口:" + endpoint + "");
sck.Bind(endpoint);
//设置监听队列
sck.Listen(10);
WriteLog("开启监听!");
//ShowMsg("开启监听!");
this.timer.Enabled = true;
//开启一个线程,放入Socket服务监听,上一篇博文中没有介绍这样的线程实例化方法。这里特别说下这样是可以的。
Thread thread = new Thread(ConnectAccept);
//设置为后台线程
thread.IsBackground = true;
thread.Start();
//IniHelper.Write("Server_" + AddressIP, DataAddress + "^" + DataName);
}
else
{
WriteLog("错误信息:数据库连接失败!");
}
}
catch (Exception ex)
{
WriteLog("错误信息:" + ex.Message);
}
}
/// <summary>
/// 判断是否有差异
/// </summary>
/// <param name="dt1"></param>
/// <param name="dt2"></param>
/// <returns></returns>
public DataTable CompareTwoDataTable(DataTable dt1, DataTable dt2)
{
dt1.Merge(dt2);
DataTable dt3 = dt2.GetChanges();
return dt3;
}
//消息框里面数据
//void ShowMsg(string str)
//{
// string Ystr = "";
// if (txt_AccMsg.Text != "")
// {
// Ystr = txt_AccMsg.Text + "\r\n";
// }
// txt_AccMsg.Text = Ystr + str;
//}
//向客户端发送数据
private void btn_SendSingleMsg_Click(object sender, EventArgs e)
{
SendSingleMsg();
}
public void SendSingleMsg(string msg = "", string IpsName = "")
{
try
{
IpsName = string.IsNullOrEmpty(IpsName) ? "" : IpsName;
string sendMsg = string.IsNullOrEmpty(msg) ? "" : msg;//获取要发送到客户端的文本
byte[] buffer = System.Text.Encoding.UTF8.GetBytes(sendMsg);//生成字节数组
if (!string.IsNullOrEmpty(IpsName))
{
string ipendpoint = IpsName;//在服务端,选择与客户端进行通信的IP地址与端口号
socketDir[ipendpoint].Send(buffer);//向客户端发送数据
//ShowMsg("向客户端发送了:" + "成功!");
}
else
{
//MessageBox.Show("请选择与哪个客户端进行通信");
}
}
catch (Exception ex)
{
WriteLog("错误信息:" + ex.Message);
}
}
// Socket newSoket = null;//.:不能将与客户端进行通信的Socket定义成全局的.
Dictionary<string, Socket> socketDir = new Dictionary<string, Socket>();//将每一个与客户端进行通信的Socket放到该集合中.
Dictionary<string, string> socketStrDir = new Dictionary<string, string>();//将每一个与客户端进行通信的userid和NAME放到该集合中.
public void ConnectAccept()
{
try
{
while (true)//注意该循环,服务端要持续监听
{
Socket newSoket = sck.Accept();//接收客户端发过来的数据,并且创建了一个新的Socket实例.
socketDir.Add(newSoket.RemoteEndPoint.ToString(), newSoket);//将负责与客户端进行通信的Socket实例添加到集合中。
//lsb_Ips.Items.Add(newSoket.RemoteEndPoint.ToString());
//ShowMsg("客户端链接成功!");
ParameterizedThreadStart par = new
ParameterizedThreadStart(RecevieMsg);
Thread thread = new Thread(par);//由于服务端接收客户端发送过来的数据是通过Recevie方法,该方法会阻断线程,所以我们重新定义一个针对该方法的线程.
// thread.SetApartmentState(ApartmentState.STA);
thread.IsBackground = true;
thread.Start(newSoket);//注意:不要忘记传递socket实例
}
}
catch (Exception ex)
{
}
}
//该方法负责接收从客户端发送过来的数据
public void RecevieMsg(object socket)
{
Socket newSocket = socket as Socket;//转成对应的Socket类型
while (true)
{
byte[] buffer = new byte[1024 * 1024 * 2];
int receiveLength = -1;
try //由于Socket中的Receive方法容易抛出异常,所以我们在这里要捕获异常。
{
receiveLength = newSocket.Receive(buffer);//接收从客户端发送过来的数据
}
catch (SocketException ex)//注意:在捕获异常时,先确定具体的异常类型。
{
//ShowMsg("出现了异常:" + ex.Message);
socketDir.Remove(newSocket.RemoteEndPoint.ToString());//如果出现了异常,将该Socket实例从集合中移除
//lsb_Ips.Items.Remove(newSocket.RemoteEndPoint.ToString());
socketStrDir.Remove(newSocket.RemoteEndPoint.ToString());
WriteLog(string.Format("{0}已断开连接", newSocket.RemoteEndPoint.ToString()));
break;//出现异常以后,终止整个循环的执行
}
catch (Exception ex)
{
//ShowMsg("出现了异常:" + ex.Message);
break;
}
if (buffer[0] == 0 && receiveLength > 1)//表示字符串
{
string str = System.Text.Encoding.UTF8.GetString(buffer, 1, receiveLength - 1);//注意,是从下标为1的开始转成字符串,为0的是标识。
WriteLog(string.Format("接收到{0}数据:{1}", newSocket.RemoteEndPoint.ToString(), str));
socketStrDir.Add(newSocket.RemoteEndPoint.ToString(), str);
//ShowMsg(str);
}
else if (buffer[0] == 1)//表示文件
{
//SaveFileDialog savafile = new SaveFileDialog();
//if (savafile.ShowDialog() == DialogResult.OK)
//{
// using (FileStream fs = new FileStream(savafile.FileName, FileMode.Create))
// {
// fs.Write(buffer, 1, receiveLength - 1);//将文件写到磁盘上,从1开始到receiveLength-1
// ShowMsg("文件写成功!");
// }
//}
}
}
}
/// <summary>
/// 循环查询数据库获取更新数据
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void OnTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
try
{
this.timer.Enabled = false;
DBConfig.Instance.ReadConfig();
DBConfig.Instance.ServerName = DataAddress;
DBConfig.Instance.DataBase = DataName;
DBConfig.Instance.CreateConnection();
//ERPInfo.Instance.UserId = DBConfig.Instance.NoticeUserID;
//ERPInfo.Instance.UserName = DBConfig.Instance.NoticeUserName;
//DataTable data = NoticeImpl.GetNoticeData2(ERPInfo.Instance.UserId);
//foreach (string item in lsb_Ips.Items)
//{
// SendSingleMsg(data.ToJsonArray(), item);
//}
foreach (string key in socketStrDir.Keys)
{
ERPInfo.Instance.UserId = socketStrDir[key].Split(',')[0];
ERPInfo.Instance.UserName = socketStrDir[key].Split(',')[1];
string SqlStr = "";
DataTable data = NoticeImpl.GetNoticeData2(ERPInfo.Instance.UserId, out SqlStr);
data = SqlHelper.ExecuteDataTable(SqlStr);
SendSingleMsg(data.ToJsonArray(), key);
//WriteLog(string.Format("UserId{0}已从数据库{1}:{2}获取到{3}条数据,发送数据到:{4},连接:{5}", ERPInfo.Instance.UserId, DataAddress, DataName, data.Rows.Count + "", key, SqlHelper._connection.ConnectionString));
}
}
catch (Exception)
{
}
finally
{
this.timer.Enabled = true;
}
}
private void StartMethod(object args)
{
this.IniControl();//初始化服务界面本机的地址值
string[] Args = args as string[];
if (Args != null && Args.Length > 0) LoadStartServer();
this.timer.Elapsed += OnTimer_Elapsed;
this.timer.Interval = 10000;
LoadStartServer();
}
private void Timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
try
{
this.Timer.Enabled = false;
if (mainThread == null)//mainThread.ThreadState == System.Threading.ThreadState.Aborted
{
ParameterizedThreadStart par = new ParameterizedThreadStart(StartMethod);
mainThread = new Thread(par);
mainThread.IsBackground = true;
mainThread.Start();
}
else if (false)
{
mainThread.Abort();
mainThread = null;
ParameterizedThreadStart par = new ParameterizedThreadStart(StartMethod);
mainThread = new Thread(par);
mainThread.IsBackground = true;
mainThread.Start();
}
}
catch (Exception)
{
}
finally
{
this.Timer.Enabled = true;
}
}
private void WriteLog(string message)
{
try
{
string path = Path.Combine(Lskj.Util.PubUtil.AbsolutelyPath + "LogFile.log");
if (File.Exists(path))
{
FileInfo fileInfo = new FileInfo(path);
if (fileInfo.Length > 1024 * 10)
{
fileInfo.Delete();
}
}
if (!Directory.Exists(Path.GetDirectoryName(path)))
Directory.CreateDirectory(Path.GetDirectoryName(path));
if (!File.Exists(path))
File.Create(path);
StreamWriter writer = File.AppendText(path);
writer.WriteLine("");
writer.WriteLine(DateTime.Now.ToString("日志记录HH:mm:ss") + " " + message + " ");
writer.Flush();
writer.Close();
}
catch (Exception)
{
}
}
protected override void OnStart(string[] args)
{
try
{
//Debugger.Launch();
ParameterizedThreadStart par = new ParameterizedThreadStart(StartMethod);
mainThread = new Thread(par);
mainThread.Start(args);
//this.Timer.Interval = 10000;
//this.Timer.Elapsed += Timer_Elapsed;
//this.Timer.Enabled = true;
}
catch (Exception)
{
}
}
protected override void OnStop()
{
}
}
}