SafeDispatch/TCPClientService/Service1.cs
2024-02-22 18:43:59 +02:00

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);
// }
//}
}
}