maher khalil Ответов: 0

Работа с оптимизацией tcplistner


Всем Привет
я работаю над системой gps слежения
сейчас я работаю над получением данных с gps устройств через tcp порт
используя класс tcpListner затем упорядочите данные и сохраните их на sql server
я создал консольное приложение для этого, а затем преобразовал его в службу windows с помощью НССМ
он работает как и ожидалось но примерно через 30 минут он потребляет всю память сервера и процессор
это всего лишь 4 подключенных устройства (тестовая фаза)

Что я уже пробовал:

using System;
using System.Threading;
using System.Net.Sockets;
using System.Text;
using System.Text.RegularExpressions;
using System.Diagnostics;
using System.Data.SqlTypes;
using System.Data.SqlClient;
using System.Data;
using Microsoft.SqlServer.Types;
using System.Linq;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            TcpListener serverSocket = new TcpListener(8889);
            TcpClient clientSocket = default(TcpClient);
            int counter = 0;
            serverSocket.Start();
            counter = 0;
            while (true)
            {
                counter += 1;
                clientSocket = serverSocket.AcceptTcpClient();
                handleClinet client = new handleClinet();
                client.startClient(clientSocket, Convert.ToString(counter));
            }
            clientSocket.Close();
            serverSocket.Stop();
           }
    }

    //Class to handle each client request separatly
    public class handleClinet
    {
       static void WriteLog(string message, EventLogEntryType type)
        {
            using (EventLog eventLog = new EventLog("Application"))
            {
                eventLog.Source = "Application";
                eventLog.WriteEntry(message, type, 101, 1);
            }
        }
        static int InsideDangerArea(double Lat, double Lng)
        {
            string point = "POINT(" + Lng + "  " + Lat + ")";
            string ConnStr = "Data Source =.; Initial Catalog=                     GPS_Tracking;Integrated Security = True";
            using (SqlConnection conn = new SqlConnection(ConnStr))
            {
          conn.Open();
       using (SqlCommand comm = new SqlCommand("Select id from T_Geofncies", conn))
                {
                    DataTable dt = new DataTable();
                    dt.Load(comm.ExecuteReader());
                   foreach (DataRow dr in dt.Rows)
                    {
                        string Query = "  DECLARE @g geometry; DECLARE @h geometry; SET @g = (select(points) from T_Geofncies where id=" + dr["id"].ToString() + " );";
                        Query += " SET @h = geometry::STGeomFromText('" + point + "', 4326); SELECT @g.STContains(@h);";
                        comm.CommandText = Query;
                        int Val = Convert.ToInt32(comm.ExecuteScalar());
                        if (Val == 1)
                        {
                            conn.Close();
                            conn.Dispose();
                            return Convert.ToInt32(dr["id"]);
                        }
                    }
                }
                conn.Close();
                conn.Dispose();
            }
            return 0;
        }

        static int OutsideSafeArea(double Lat, double Lng)
        {

            string point = "POINT(" + Lng + "  " + Lat + ")";

            string ConnStr = "Data Source =.; Initial Catalog = GPS_Tracking;Integrated Security = True";
            using (SqlConnection conn = new SqlConnection(ConnStr))
            {
                conn.Open();
                using (SqlCommand comm = new SqlCommand("Select id from T_SafeArea", conn))
                {
                    DataTable dt = new DataTable();
                    dt.Load(comm.ExecuteReader());

                    foreach (DataRow dr in dt.Rows)
                    {
                        string Query = "  DECLARE @g geometry; DECLARE @h geometry; SET @g = (select(points) from T_SafeArea where id=" + dr["id"].ToString() + " );";
                        Query += " SET @h = geometry::STGeomFromText('" + point + "', 4326); SELECT @g.STContains(@h);";
                        comm.CommandText = Query;
                        int Val = Convert.ToInt32(comm.ExecuteScalar());
                        if (Val == 1)
                        {
                            conn.Close();
                            conn.Dispose();
                            return Convert.ToInt32(dr["id"]);
                        }

                    }
                }
                conn.Close();
                conn.Dispose();
            }
            return 0;
        }
        static SqlGeography GetGeographyFromText(String pText)
        {
            SqlString ss = new SqlString(pText);
            SqlChars sc = new SqlChars(ss);
            try
            {
                return SqlGeography.STPointFromText(sc, 4326);
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
        TcpClient clientSocket;
        string clNo;
        public void startClient(TcpClient inClientSocket, string clineNo)
        {
            this.clientSocket = inClientSocket;
            this.clNo = clineNo;
            Thread ctThread = new Thread(doChat);
            ctThread.Start();
        }
        private void doChat()
        {
            string ConnStr = "Data Source =.; Initial Catalog = GPS_Tracking;Integrated Security = True";

            int requestCount = 0;
            // byte[] bytesFrom = new byte[10025];
            string dataFromClient = null;
            Byte[] sendBytes = null;
            string serverResponse = null;
            string rCount = null;
            requestCount = 0;

            while ((true))
            {
                try
                {
                    requestCount = requestCount + 1;
                    NetworkStream networkStream = clientSocket.GetStream();
                    int i;
                    int size = (int)clientSocket.ReceiveBufferSize;
                    // Loop to receive all the data sent by the client.
                    Byte[] bytes = new Byte[size];
                    string data = "";
                    string IMEI;
                    while ((i = networkStream.Read(bytes, 0, bytes.Length)) != 0)
                    {

                        try
                        {
                            data = System.Text.Encoding.ASCII.GetString(bytes, 0, i);

                            string[] tokens = data.Split(new[] { "GPRMC" }, StringSplitOptions.None);
                            var longest = Regex.Matches(data, @"\d+").Cast<match>().OrderByDescending(m => m.Length).First();


                            IMEI = longest.ToString();
                            if (IMEI.Length > 15)
                                IMEI = IMEI.Substring(1);



                            foreach (string item in tokens)
                            {
                                try
                                {
                                    string[] Values = item.Split(',');                                   // Console.WriteLine("Received: {0}", data);
                                    string time = Values[1];
                                    // Console.WriteLine("Time= " + time);
                                    string lat;
                                    string lng;
                                    string speed;
                                    string date;

                                    lat = Values[3];
                                    lng = Values[5];
                                    speed = Values[7];
                                    date = Values[9];

                                    string NewDString = date.Substring(2, 2) + date.Substring(0, 2) + date.Substring(4, 2);

                                    //  Console.WriteLine("IMEI= " + IMEI);

                                    // Alternate choice: If the string has been input by an end user, you might  
                                    // want to format it according to the current culture: 
                                    // IFormatProvider culture = System.Threading.Thread.CurrentThread.CurrentCulture;
                                    string myDate = (NewDString + time).Insert(2, "-").Insert(5, "-").Insert(8, " ").Insert(11, ":").Insert(14, ":");


                                    double latDeg = Convert.ToDouble(Convert.ToDouble(lat).ToString().Substring(0, 2));
                                    double latMin = Convert.ToDouble(Convert.ToDouble(lat).ToString().Substring(2));

                                    double lngDeg = Convert.ToDouble(Convert.ToDouble(lng).ToString().Substring(0, 2));
                                    double lngmin = Convert.ToDouble(Convert.ToDouble(lng).ToString().Substring(2));

                                    double latmap = latDeg + (latMin / 60);
                                    //  OldLat=
                                    double lngmap = lngDeg + (lngmin / 60);
                                    //if ((Math.Round(latmap, 3) != Math.Round(OldLat, 3) && Math.Round(lngmap, 3) != Math.Round(OldLng, 3)) || idleRecord > 30)
                                    //{
                                    using (SqlConnection conn = new SqlConnection(ConnStr))
                                    {
                                        conn.Open();
                                        using (SqlCommand cmd = conn.CreateCommand())
                                        {
                                            // DbCommand also implements IDisposable

                                            // create command with placeholders
                                            cmd.CommandText =
                                               "INSERT INTO T_Tracking " +
                                               "([IMEI], [TrackTime],  [Longitude], [Lattitude],  [speed],[MapPoint],[SafeAreaID],[GeoFenceID]) " +
                                               "VALUES(@IMEI, @TrackTime,  @Longitude, @Lattitude,  @speed,@MapPoint,@SafeAreaID,@GeoFenceID)";


                                            SqlParameter p_IMEI = new SqlParameter("@IMEI", IMEI);
                                            cmd.Parameters.Add(p_IMEI);

                                            SqlParameter p_TrackTime = new SqlParameter("@TrackTime", myDate);
                                            cmd.Parameters.Add(p_TrackTime);

                                            SqlParameter p_Longitude = new SqlParameter("@Longitude", lngmap);
                                            cmd.Parameters.Add(p_Longitude);

                                            SqlParameter p_Lattitude = new SqlParameter("@Lattitude", latmap);
                                            cmd.Parameters.Add(p_Lattitude);

                                            SqlParameter p_Speed = new SqlParameter("@speed", speed);
                                            cmd.Parameters.Add(p_Speed);
                                            SqlParameter p_Points = new SqlParameter("@MapPoint", System.Data.SqlDbType.Udt);
                                            p_Points.UdtTypeName = "geometry";
                                            p_Points.Value = GetGeographyFromText("Point(" + lngmap + "  " + latmap + ") ");
                                            cmd.Parameters.Add(p_Points);
                                            SqlParameter P_Safe = new SqlParameter("@SafeAreaID", OutsideSafeArea(latmap, lngmap));
                                            cmd.Parameters.Add(P_Safe);
                                            SqlParameter P_GeoFence = new SqlParameter("@GeoFenceID", InsideDangerArea(latmap, lngmap));
                                            cmd.Parameters.Add(P_GeoFence);
                                            // execute
                                            cmd.ExecuteNonQuery();

                                        }
                                        //}
                                        //else
                                        //    idleRecord = idleRecord + 1;

                                    }
                                }
                                catch (Exception exp) { WriteLog(exp.ToString(), EventLogEntryType.Error); }
                            }

                            
                        }
                        catch { }
                    }
                  
                }
                catch (Exception ex)
                {
                    // Console.WriteLine(" >> " + ex.ToString());
                }
            }
        }
    }
}

0 Ответов