ab56a9bcf7
SVN-Revision: r240
380 lines
16 KiB
C#
380 lines
16 KiB
C#
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()
|
||
{
|
||
|
||
}
|
||
}
|
||
}
|