377 lines
15 KiB
C#
377 lines
15 KiB
C#
|
using System;
|
|||
|
using System.Diagnostics;
|
|||
|
using System.Linq;
|
|||
|
using System.ServiceProcess;
|
|||
|
using System.Text;
|
|||
|
using System.Configuration;
|
|||
|
using System.Threading;
|
|||
|
using System.Collections;
|
|||
|
using System.Net.Sockets;
|
|||
|
using System.Net;
|
|||
|
using System.Timers;
|
|||
|
using System.Threading.Tasks;
|
|||
|
|
|||
|
namespace WindowsService1
|
|||
|
{
|
|||
|
public partial class Service1 : ServiceBase
|
|||
|
{
|
|||
|
public static volatile UdpMulticast UdpMulti = null;
|
|||
|
public static volatile Queue MessageSend = new Queue();
|
|||
|
public static volatile Boolean appDead = false;
|
|||
|
public static NetworkStream clientStream = null;
|
|||
|
public static TcpClient client = null;
|
|||
|
private RegistrationThread RegConn = null;
|
|||
|
public static Thread RegistrationThreadObj = null;
|
|||
|
public static string ip_multicast = string.Empty;
|
|||
|
public static string port_multicast = string.Empty;
|
|||
|
public static string TcpPort = string.Empty;
|
|||
|
public static string TcpServerIP = string.Empty;
|
|||
|
public static string LocalIP = string.Empty;
|
|||
|
static string logFile = "log.log";
|
|||
|
public Service1()
|
|||
|
{
|
|||
|
InitializeComponent();
|
|||
|
// Turn off autologging
|
|||
|
this.AutoLog = false;
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
protected override void OnStart(string[] args)
|
|||
|
{
|
|||
|
//writeToFile("Service started!");
|
|||
|
Utils.WriteEventLog("Safemobile", "SERVICE ON", EventLogEntryType.Information, 34500);
|
|||
|
|
|||
|
if (!ConfigurationManager.AppSettings.AllKeys.Contains("ip_multicast"))
|
|||
|
{
|
|||
|
Utils.WriteEventLog("Safemobile", "AppSettings does not contain key \"ip_multicast\"", EventLogEntryType.Error, 23456);
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
ip_multicast = ConfigurationManager.AppSettings["ip_multicast"];
|
|||
|
Utils.WriteEventLog("Safemobile", "AppSettings.ip_multicast = \"" + ip_multicast + "\"", EventLogEntryType.Information, 34500);
|
|||
|
}
|
|||
|
|
|||
|
if (!ConfigurationManager.AppSettings.AllKeys.Contains("port_multicast"))
|
|||
|
{
|
|||
|
Utils.WriteEventLog("Safemobile", "AppSettings does not contain key \"port_multicast\"", EventLogEntryType.Error, 23456);
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
port_multicast = ConfigurationManager.AppSettings["port_multicast"];
|
|||
|
Utils.WriteEventLog("Safemobile", "AppSettings.port_multicast = \"" + port_multicast + "\"", EventLogEntryType.Information, 34500);
|
|||
|
}
|
|||
|
|
|||
|
if (!ConfigurationManager.AppSettings.AllKeys.Contains("TcpPort"))
|
|||
|
{
|
|||
|
Utils.WriteEventLog("Safemobile", "AppSettings does not contain key \"TcpPort\"", EventLogEntryType.Error, 23456);
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
TcpPort = ConfigurationManager.AppSettings["TcpPort"];
|
|||
|
Utils.WriteEventLog("Safemobile", "AppSettings.TcpPort = \"" + TcpPort + "\"", EventLogEntryType.Information, 34500);
|
|||
|
}
|
|||
|
|
|||
|
if (!ConfigurationManager.AppSettings.AllKeys.Contains("TcpServerIP"))
|
|||
|
{
|
|||
|
Utils.WriteEventLog("Safemobile", "AppSettings does not contain key \"TcpServerIP\"", EventLogEntryType.Error, 23456);
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
TcpServerIP = ConfigurationManager.AppSettings["TcpServerIP"];
|
|||
|
Utils.WriteEventLog("Safemobile", "AppSettings.TcpServerIP = \"" + TcpServerIP + "\"", EventLogEntryType.Information, 34500);
|
|||
|
}
|
|||
|
|
|||
|
if (!ConfigurationManager.AppSettings.AllKeys.Contains("LocalIP"))
|
|||
|
{
|
|||
|
Utils.WriteEventLog("Safemobile", "AppSettings does not contain key \"LocalIP\"", EventLogEntryType.Error, 23456);
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
LocalIP = ConfigurationManager.AppSettings["LocalIP"];
|
|||
|
Utils.WriteEventLog("Safemobile", "AppSettings.LocalIP = \"" + LocalIP + "\"", EventLogEntryType.Information, 34500);
|
|||
|
}
|
|||
|
|
|||
|
try
|
|||
|
{
|
|||
|
System.Timers.Timer timer1 = new System.Timers.Timer();
|
|||
|
timer1.Elapsed += new ElapsedEventHandler(timer1_Elapsed);
|
|||
|
timer1.Interval = 20000;
|
|||
|
timer1.Enabled = true;
|
|||
|
timer1.Start();
|
|||
|
|
|||
|
StartPingThread();
|
|||
|
|
|||
|
UdpMulti = new UdpMulticast(ip_multicast, Convert.ToInt32(port_multicast));
|
|||
|
UdpMulti.StartListen(LocalIP);
|
|||
|
UdpMulti.OnNewDataRecv += new UdpMulticast.newData4Send(udp_OnNewDataRecv);
|
|||
|
|
|||
|
client = new TcpClient();
|
|||
|
IPEndPoint serverEndPoint = new IPEndPoint(IPAddress.Parse(TcpServerIP), Convert.ToInt32(TcpPort));
|
|||
|
client.Connect(serverEndPoint);
|
|||
|
Utils.WriteEventLog("Safemobile", "Client connected at: " + TcpServerIP, EventLogEntryType.Information, 23456);
|
|||
|
//writeToFile("Client connected at: " + TcpServerIP + " " + DateTime.Now.ToString());
|
|||
|
clientStream = client.GetStream();
|
|||
|
System.Text.UTF8Encoding encoding = new System.Text.UTF8Encoding();
|
|||
|
|
|||
|
RegConn = new RegistrationThread(clientStream);
|
|||
|
RegConn.OnPong += RegConn_OnPong;
|
|||
|
RegistrationThreadObj = new Thread(new ThreadStart(RegConn.handleConnection));
|
|||
|
RegistrationThreadObj.IsBackground = true;
|
|||
|
RegistrationThreadObj.Start();
|
|||
|
|
|||
|
}
|
|||
|
catch (Exception ex)
|
|||
|
{
|
|||
|
Utils.WriteEventLog("Safemobile", "Error conecting to Multicast" + ex.ToString(), EventLogEntryType.Error, 23456);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
private DateTime lastPongTime = DateTime.Now;
|
|||
|
private DateTime lastPingTime = DateTime.Now;
|
|||
|
|
|||
|
private void RegConn_OnPong()
|
|||
|
{
|
|||
|
|
|||
|
lastPongTime = DateTime.Now;
|
|||
|
}
|
|||
|
|
|||
|
bool running = false;
|
|||
|
|
|||
|
private readonly int PING_TIME_OUT_MS = 5000;
|
|||
|
|
|||
|
private void StartPingThread()
|
|||
|
{
|
|||
|
running = true;
|
|||
|
Task.Factory.StartNew(() =>
|
|||
|
{
|
|||
|
int count = 0;
|
|||
|
while (running)
|
|||
|
{
|
|||
|
if (count++ > PING_TIME_OUT_MS / 100)
|
|||
|
{
|
|||
|
try
|
|||
|
{
|
|||
|
String str = "PING";
|
|||
|
|
|||
|
int lostPongs = (int)((DateTime.Now - lastPongTime).TotalMilliseconds / PING_TIME_OUT_MS);
|
|||
|
if (lostPongs > 0)
|
|||
|
str += lostPongs;
|
|||
|
|
|||
|
lastPingTime = DateTime.Now;
|
|||
|
clientStream.Write(asen.GetBytes(str), 0, asen.GetBytes(str).Length);
|
|||
|
Utils.WriteEventLog("Safemobile", $"{str} sent @{TcpServerIP}", EventLogEntryType.Information, 23456);
|
|||
|
}
|
|||
|
catch
|
|||
|
{
|
|||
|
}
|
|||
|
finally
|
|||
|
{
|
|||
|
count = 0;
|
|||
|
}
|
|||
|
|
|||
|
/*
|
|||
|
if((DateTime.Now - lastPongTime).TotalMilliseconds > PING_TIME_OUT_MS * 3)
|
|||
|
{
|
|||
|
String serviceName = GetServiceName();
|
|||
|
Process process = new Process();
|
|||
|
process.StartInfo.FileName = "cmd";
|
|||
|
process.StartInfo.Arguments = $"/c net stop \"{serviceName}\" & net start \"{serviceName}\"";
|
|||
|
process.Start();
|
|||
|
|
|||
|
Environment.Exit(1);
|
|||
|
}*/
|
|||
|
}
|
|||
|
Thread.Sleep(100);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
});
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
protected String GetServiceName()
|
|||
|
{
|
|||
|
// Calling System.ServiceProcess.ServiceBase::ServiceNamea allways returns
|
|||
|
// an empty string,
|
|||
|
// see https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=387024
|
|||
|
|
|||
|
// So we have to do some more work to find out our service name, this only works if
|
|||
|
// the process contains a single service, if there are more than one services hosted
|
|||
|
// in the process you will have to do something else
|
|||
|
|
|||
|
int processId = System.Diagnostics.Process.GetCurrentProcess().Id;
|
|||
|
String query = "SELECT * FROM Win32_Service where ProcessId = " + processId;
|
|||
|
System.Management.ManagementObjectSearcher searcher =
|
|||
|
new System.Management.ManagementObjectSearcher(query);
|
|||
|
|
|||
|
foreach (System.Management.ManagementObject queryObj in searcher.Get())
|
|||
|
{
|
|||
|
return queryObj["Name"].ToString();
|
|||
|
}
|
|||
|
|
|||
|
throw new Exception("Can not get the ServiceName");
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
static bool IsConnected(TcpClient TCPclient)
|
|||
|
{
|
|||
|
if (TCPclient.Connected)
|
|||
|
{
|
|||
|
if ((TCPclient.Client.Poll(0, SelectMode.SelectWrite)) && (!TCPclient.Client.Poll(0, SelectMode.SelectError)))
|
|||
|
{
|
|||
|
byte[] buffer = new byte[1];
|
|||
|
if (TCPclient.Client.Receive(buffer, SocketFlags.Peek) == 0)
|
|||
|
{
|
|||
|
return false;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
return true;
|
|||
|
}
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
return false;
|
|||
|
}
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
return false;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
public static volatile String FromQue = "";
|
|||
|
public static volatile ASCIIEncoding asen = new ASCIIEncoding();
|
|||
|
static void udp_OnNewDataRecv(byte[] data, int dataLen)
|
|||
|
{
|
|||
|
try
|
|||
|
{
|
|||
|
string str = System.Text.Encoding.ASCII.GetString(data, 0, dataLen);
|
|||
|
//Utils.WriteEventLog("Safemobile", "Recive data on Multicast Send on TCP: " + str, EventLogEntryType.Information, 34500);
|
|||
|
|
|||
|
if (FromQue.Length == 0)
|
|||
|
{
|
|||
|
if (MessageSend.Count > 0)
|
|||
|
FromQue = MessageSend.Dequeue().ToString();
|
|||
|
}
|
|||
|
|
|||
|
if(clientStream == null)
|
|||
|
{
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
if (FromQue.Length == 0)
|
|||
|
clientStream.Write(asen.GetBytes(str), 0, asen.GetBytes(str).Length);
|
|||
|
else
|
|||
|
{
|
|||
|
if (FromQue.CompareTo(str) == 0)
|
|||
|
{
|
|||
|
FromQue = "";
|
|||
|
}
|
|||
|
else
|
|||
|
clientStream.Write(asen.GetBytes(str), 0, asen.GetBytes(str).Length);
|
|||
|
}
|
|||
|
|
|||
|
if (FromQue.Length == 0)
|
|||
|
{
|
|||
|
if (MessageSend.Count > 0)
|
|||
|
FromQue = MessageSend.Dequeue().ToString();
|
|||
|
}
|
|||
|
}
|
|||
|
catch (Exception ex)
|
|||
|
{
|
|||
|
Utils.WriteEventLog("Safemobile", "Erorr on upd rec:" + ex.ToString(), EventLogEntryType.Error, 23456);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
protected override void OnStop()
|
|||
|
{
|
|||
|
Utils.WriteEventLog("Safemobile", "SERVICE OFF", EventLogEntryType.Information, 34500);
|
|||
|
running = false;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
private void timer1_Elapsed(object sender, EventArgs e)
|
|||
|
{
|
|||
|
//Utils.WriteEventLog("Safemobile", "Enter on TIMER", EventLogEntryType.Information, 34500);
|
|||
|
try
|
|||
|
{
|
|||
|
Boolean IsConnected = false;
|
|||
|
//Utils.WriteEventLog("Safemobile", "PAS1", EventLogEntryType.Information, 34500);
|
|||
|
if (client != null && client.Connected)
|
|||
|
{
|
|||
|
//Utils.WriteEventLog("Safemobile", "PAS2", EventLogEntryType.Information, 34500);
|
|||
|
if ((client.Client.Poll(0, SelectMode.SelectWrite)) && (!client.Client.Poll(0, SelectMode.SelectError)))
|
|||
|
{
|
|||
|
//Utils.WriteEventLog("Safemobile", "PAS3", EventLogEntryType.Information, 34500);
|
|||
|
byte[] buffer = new byte[1];
|
|||
|
if (client.Client.Receive(buffer, SocketFlags.Peek) == 0)
|
|||
|
;
|
|||
|
else IsConnected = true;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
if (IsConnected)
|
|||
|
{
|
|||
|
Utils.WriteEventLog("Safemobile", "TCP is still ON", EventLogEntryType.Information, 34500);
|
|||
|
running = true;
|
|||
|
}
|
|||
|
|
|||
|
else
|
|||
|
{
|
|||
|
Utils.WriteEventLog("Safemobile", "TCP is OFF", EventLogEntryType.Information, 34500);
|
|||
|
|
|||
|
// close client if not null
|
|||
|
|
|||
|
clientStream?.Close();
|
|||
|
client?.Close();
|
|||
|
|
|||
|
|
|||
|
RegistrationThreadObj?.Join(2000);
|
|||
|
Thread.Sleep(200);
|
|||
|
Utils.WriteEventLog("Safemobile", "Distroy Thread and client", EventLogEntryType.Information, 34500);
|
|||
|
client = new TcpClient();
|
|||
|
IPEndPoint serverEndPoint = new IPEndPoint(IPAddress.Parse(TcpServerIP), Convert.ToInt32(TcpPort));
|
|||
|
client.Connect(serverEndPoint);
|
|||
|
Utils.WriteEventLog("Safemobile", "Client connected at: " + serverEndPoint, EventLogEntryType.Information, 23456);
|
|||
|
//writeToFile("Client connected at: " + serverEndPoint.ToString() + " " + DateTime.Now.ToString());
|
|||
|
clientStream = client.GetStream();
|
|||
|
System.Text.UTF8Encoding encoding = new System.Text.UTF8Encoding();
|
|||
|
RegConn = new RegistrationThread(clientStream);
|
|||
|
RegConn.OnPong += RegConn_OnPong;
|
|||
|
RegistrationThreadObj = new Thread(new ThreadStart(RegConn.handleConnection));
|
|||
|
RegistrationThreadObj.IsBackground = true;
|
|||
|
RegistrationThreadObj.Start();
|
|||
|
//Utils.WriteEventLog("Safemobile", "End renew the thread and client", EventLogEntryType.Information, 34500);
|
|||
|
}
|
|||
|
}
|
|||
|
catch (Exception ex)
|
|||
|
{
|
|||
|
//writeToFile("Client disconnected " + DateTime.Now.ToString());
|
|||
|
Utils.WriteEventLog("Safemobile", "Error on timer: " + ex.ToString(), EventLogEntryType.Error, 23456);
|
|||
|
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
//internal static void writeToFile(string message)
|
|||
|
//{
|
|||
|
// try
|
|||
|
// {
|
|||
|
// Utils.WriteEventLog("Safemobile", "enter write to file", EventLogEntryType.SuccessAudit, 23456);
|
|||
|
// if (!File.Exists(logFile))
|
|||
|
// File.Create(logFile);
|
|||
|
// File.WriteAllText(logFile, message);
|
|||
|
// Utils.WriteEventLog("Safemobile", "exit write to file", EventLogEntryType.SuccessAudit, 23456);
|
|||
|
// }
|
|||
|
// catch
|
|||
|
// {
|
|||
|
// Utils.WriteEventLog("Safemobile", "unable to write to file", EventLogEntryType.SuccessAudit, 23456);
|
|||
|
// }
|
|||
|
//}
|
|||
|
|
|||
|
}
|
|||
|
}
|
|||
|
|