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; namespace TCPServerService { 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 volatile ArrayList listOFSocket = new ArrayList(); static string logFile = System.AppDomain.CurrentDomain.BaseDirectory + "\\log.log"; private static RegistrationThread RegistrationConnection; public Service1() { InitializeComponent(); // Turn off autologging this.AutoLog = false; } protected override void OnStart(string[] args) { //writeToFile("Service started"); Utils.WriteEventLog(Program.COMPANY, "SERVICE ON", EventLogEntryType.Information, 34555); string ip_multicast = string.Empty; string port_multicast = string.Empty; string TcpPort = string.Empty; string localIP = string.Empty; bool checkForPings = false; if (!ConfigurationManager.AppSettings.AllKeys.Contains("ip_multicast")) { Utils.WriteEventLog(Program.COMPANY, "AppSettings does not contain key \"ip_multicast\"", EventLogEntryType.Error, 23456); } else { ip_multicast = ConfigurationManager.AppSettings["ip_multicast"]; Utils.WriteEventLog(Program.COMPANY, "AppSettings.ip_multicast = \"" + ip_multicast + "\"", EventLogEntryType.Information, 34500); } if (!ConfigurationManager.AppSettings.AllKeys.Contains("port_multicast")) { Utils.WriteEventLog(Program.COMPANY, "AppSettings does not contain key \"port_multicast\"", EventLogEntryType.Error, 23456); } else { port_multicast = ConfigurationManager.AppSettings["port_multicast"]; Utils.WriteEventLog(Program.COMPANY, "AppSettings.port_multicast = \"" + port_multicast + "\"", EventLogEntryType.Information, 34500); } if (!ConfigurationManager.AppSettings.AllKeys.Contains("TcpPort")) { Utils.WriteEventLog(Program.COMPANY, "AppSettings does not contain key \"TcpPort\"", EventLogEntryType.Error, 23456); } else { TcpPort = ConfigurationManager.AppSettings["TcpPort"]; Utils.WriteEventLog(Program.COMPANY, "AppSettings.TcpPort = \"" + TcpPort + "\"", EventLogEntryType.Information, 34500); } if (!ConfigurationManager.AppSettings.AllKeys.Contains("LocalIP")) { Utils.WriteEventLog(Program.COMPANY, "AppSettings does not contain key \"LocalIP\"", EventLogEntryType.Error, 23456); } else { localIP = ConfigurationManager.AppSettings["LocalIP"]; Utils.WriteEventLog(Program.COMPANY, "AppSettings.LocalIP = \"" + TcpPort + "\"", EventLogEntryType.Information, 34500); } if (!ConfigurationManager.AppSettings.AllKeys.Contains("CheckForPings")) { Utils.WriteEventLog(Program.COMPANY, "AppSettings does not contain key \"CheckForPings\"", EventLogEntryType.Error, 23456); } else { Boolean.TryParse(ConfigurationManager.AppSettings["CheckForPings"], out checkForPings); Utils.WriteEventLog(Program.COMPANY, "AppSettings.CheckForPings = \"" + TcpPort + "\"", EventLogEntryType.Information, 34500); } try { UdpMulti = new UdpMulticast(ip_multicast,Convert.ToInt32(port_multicast)); UdpMulti.StartListen(localIP); UdpMulti.OnNewDataRecv += new UdpMulticast.newData4Send(udp_OnNewDataRecv); RegistrationConnection = new RegistrationThread(Convert.ToInt32(TcpPort)); RegistrationConnection.checkForPings = checkForPings; Thread LocationThreadObj = new Thread(new ThreadStart(RegistrationConnection.handleConnection)); LocationThreadObj.IsBackground = true; LocationThreadObj.Start(); Thread consumeQueuesThread = new Thread(new ThreadStart(ConsumeUdpMessages)); consumeQueuesThread.IsBackground = true; consumeQueuesThread.Start(); } catch (Exception ex) { Utils.WriteEventLog(Program.COMPANY, "Error conecting to Multicast" + ex.ToString(), EventLogEntryType.Error, 23456); } } private static void ConsumeUdpMessages() { while(true) { string str = udpMessagesQueue.GetItem(500); if(str == null || str.Equals(String.Empty)) { Thread.Sleep(1); continue; } //Utils.WriteEventLog(Program.COMPANY, "Recive data on Multicast Send on TCP: " + str, EventLogEntryType.Information, 34500); if (FromQue.Length == 0) { if (MessageSend.Count > 0) FromQue = MessageSend.Dequeue().ToString(); } if (FromQue.Length == 0) { Socket ErrorObj = null; Boolean retry = true; while (retry) { try { retry = false; foreach (Socket obj in listOFSocket) { ErrorObj = obj; obj.Send(asen.GetBytes(str), asen.GetBytes(str).Length, SocketFlags.None); } } catch (Exception ex) { if (ErrorObj != null) { String clientIP = ((IPEndPoint)ErrorObj.RemoteEndPoint).Address.ToString(); if (RegistrationConnection != null) RegistrationConnection.onUdpSendingFailed(clientIP); //listOFSocket.Remove(ErrorObj); Utils.WriteEventLog(Program.COMPANY, $"Failed to send data to {clientIP}. Total connections: " + Service1.listOFSocket.Count, EventLogEntryType.Information, 34500); //writeToFile(string.Format("Total connections: {0} {1}", Service1.listOFSocket.Count.ToString(), DateTime.Now.ToString())); retry = true; } } } } else { if (FromQue.CompareTo(str) == 0) { FromQue = ""; } else { Socket ErrorObj = null; Boolean retry = true; while (retry) { try { retry = false; foreach (Socket obj in listOFSocket) { ErrorObj = obj; obj.Send(asen.GetBytes(str), asen.GetBytes(str).Length, SocketFlags.None); } } catch (Exception ex) { if (ErrorObj != null) { String clientIP = ((IPEndPoint)ErrorObj.RemoteEndPoint).Address.ToString(); if (RegistrationConnection != null) RegistrationConnection.onUdpSendingFailed(clientIP); //listOFSocket.Remove(ErrorObj); Utils.WriteEventLog(Program.COMPANY, $"Failed to send data to {clientIP}. Total connections: " + Service1.listOFSocket.Count, EventLogEntryType.Information, 34500); //writeToFile(string.Format("Total connections: {0} {1}" , Service1.listOFSocket.Count.ToString() , DateTime.Now.ToString())); retry = true; } } } ///foreach (Socket obj in listOFSocket) /// obj.Send(asen.GetBytes(str), asen.GetBytes(str).Length, SocketFlags.None); } } } } public static volatile String FromQue = ""; public static volatile ASCIIEncoding asen = new ASCIIEncoding(); private static InterthreadMessageQueue udpMessagesQueue = new InterthreadMessageQueue(); static void udp_OnNewDataRecv(byte[] data, int dataLen) { try { string str = System.Text.Encoding.ASCII.GetString(data, 0, dataLen); udpMessagesQueue.PostItem(str); } catch (Exception ex) { Utils.WriteEventLog(Program.COMPANY, "Erorr on upd rec:" + ex.ToString(), EventLogEntryType.Error, 23456); } } protected override void OnStop() { Utils.WriteEventLog(Program.COMPANY, "SERVICE OFF", EventLogEntryType.Information, 35555); } //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(Exception ex) // { // Utils.WriteEventLog("Safemobile", "unable to write to file" + ex, EventLogEntryType.SuccessAudit, 23456); // } //} } }