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;
///
/// 旧的数据源存储
///
public DataTable oldData = new DataTable();
Socket sck = null;
//Thread thread = null;
///
/// 初始化界面的本机ip地址值和端口
///
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();
//}
///
/// 建立soket数据方法
///
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);
}
}
///
/// 判断是否有差异
///
///
///
///
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 socketDir = new Dictionary();//将每一个与客户端进行通信的Socket放到该集合中.
Dictionary socketStrDir = new Dictionary();//将每一个与客户端进行通信的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("文件写成功!");
// }
//}
}
}
}
///
/// 循环查询数据库获取更新数据
///
///
///
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()
{
}
}
}