SafeDispatch/TCPServerService/RegistrationThread.cs

130 lines
5.2 KiB
C#

using System;
using System.Collections.Generic;
using System.Net.Sockets;
using System.Threading;
using System.Net;
using System.Diagnostics;
namespace TCPServerService
{
class RegistrationThread
{
int port;
private Socket socket;
private List<ReadThread> allThreads = new List<ReadThread>();
public bool checkForPings = true;
public RegistrationThread(int registrationPort)
{
port = registrationPort;
}
public void handleConnection()
{
Utils.WriteEventLog(Program.COMPANY, "Registration Thread - Initialized on Port " + port, EventLogEntryType.Information, 34500);
TcpListener myListener = new TcpListener(IPAddress.Any, port);
myListener.Start();
int count = 0;
while (true)
{
try
{
socket = myListener.AcceptSocket();
String clientIP = ((IPEndPoint)socket.RemoteEndPoint).Address.ToString();
Utils.WriteEventLog(Program.COMPANY, "IP " + clientIP + " connected", EventLogEntryType.Information, 34500);
Service1.listOFSocket.Add(socket);
Utils.WriteEventLog(Program.COMPANY, "Total connections: " + Service1.listOFSocket.Count, EventLogEntryType.Information, 34500);
//Service1.writeToFile(string.Format("Total connections: {0} {1}", Service1.listOFSocket.Count.ToString(), DateTime.Now.ToString()));
ReadThread RegistrationConnection = new ReadThread(socket);
RegistrationConnection.OnReadException += RegistrationConnection_OnReadException;
Thread LocationThreadObj = new Thread(new ThreadStart(RegistrationConnection.handleConnection));
LocationThreadObj.IsBackground = true;
LocationThreadObj.Start();
allThreads.Add(RegistrationConnection);
}
catch (Exception e)
{
Utils.WriteEventLog(Program.COMPANY, "Ex in appserver:Registration thread: " + e.ToString(), EventLogEntryType.Error, 23456);
//Form1.appDead = true;
}
Thread.Sleep(1);
if (count++ > 5000)
{
RemoveClient(null);
count = 0;
}
}
//myListener.Stop();
}
private void RegistrationConnection_OnReadException(string clientIP)
{
RemoveClient(clientIP);
}
private Object _lock = new Object();
private void RemoveClient(String clientIP)
{
lock (_lock)
{
try
{
// create list to store the threads that needs to be removed
List<ReadThread> toRemove = new List<ReadThread>();
// iterate all active threads to search for lost pings
foreach (ReadThread thread in allThreads)
{
bool pingExpired = checkForPings && (ReadThread.PING_INTERVAL_SEC * 3) < (DateTime.Now - thread.lastPingTime).TotalSeconds;
//Utils.WriteEventLog(Program.COMPANY, "PING: " + thread.lastPingTime.ToShortDateString() + " | | | "
// + (DateTime.Now - thread.lastPingTime).TotalSeconds, EventLogEntryType.SuccessAudit, 23456);
// if 3 pings were lost
if (pingExpired || (clientIP != null && thread.clientIP.Equals(clientIP)))
{
try
{
Utils.WriteEventLog(Program.COMPANY, $"Closing socket with {thread.clientIP} {(pingExpired ? "due to lost PINGS" : "closed socket")}", EventLogEntryType.Warning, 23456);
// close connection, remove it and then flag it as to be removed
thread.socket.Close();
Service1.listOFSocket.Remove(thread.socket);
toRemove.Add(thread);
}
catch (Exception ex)
{
Utils.WriteEventLog(Program.COMPANY, "Unable to close socket: " + ex.ToString(), EventLogEntryType.Error, 23456);
}
}
}
// remove all threads that are closed due to inactive ping
foreach (ReadThread thread in toRemove)
{
thread.isRunning = false;
allThreads.Remove(thread);
}
}
catch(Exception ex)
{
Utils.WriteEventLog(Program.COMPANY, "Error removing client : " + ex.ToString(), EventLogEntryType.Error, 23456);
}
}
}
public void onUdpSendingFailed(String clientIP)
{
RemoveClient(clientIP);
}
}
}