130 lines
5.2 KiB
C#
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);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|