दिलचस्प पोस्ट
पीडीओ PHP में क्वेरी त्रुटि को कैसे देखें नेस्टेड टुकड़ों से मूल टुकड़े तक डेटा भेजना क्या मैं एक .png छवि को एक html पृष्ठ में एम्बेड कर सकता हूं? शामिल करें। एंड्रॉइड स्टूडियो में एपीके में पुस्तकालय RabbitMQ 3.3.1 अतिथि / अतिथि के साथ लॉगिन नहीं कर सकता क्रॉस मूल अनुरोध केवल HTTP के लिए समर्थित हैं लेकिन यह क्रॉस-डोमेन नहीं है अजीब शाखाएं प्रदर्शन पूर्वाभ्यास 3.0 माइग्रेशन: हेडर्स और एचटीटीपी बॉडी के साथ पोस्ट कैसे करें क्या इकाई फ़्रेमवर्क प्रसंग को वक्तव्य का उपयोग करना चाहिए? गलती से स्वामी के पास वापस लौटा, अनगिनत परिवर्तन खो गए एक निश्चित समय के बाद कमांड लाइन को स्वतः-मारने के लिए कमांड लाइन कमांड वर्ग के नाम से तत्व कैसे प्राप्त करें? रेगेक्स: प्रश्न चिह्न और बृहदान्त्र विशिष्ट पंक्तियों के लिए MYSQL राशि () HTTP स्टेटस कोड 200 (कैश) बनाम स्टेटस कोड 304 में क्या अंतर है?

सी # में उच्च प्रदर्शन टीसीपी सर्वर

मैं एक अनुभवी सी # डेवलपर हूं, लेकिन मैंने अभी तक एक टीसीपी सर्वर अनुप्रयोग विकसित नहीं किया है। अब मुझे एक उच्च स्केलेबल और उच्च निष्पादन सर्वर विकसित करना है जो कम से कम 5-10 हजार समसामयिक कनेक्शन को नियंत्रित कर सकता है: जीपीएस उपकरणों से जीआरपीआरएस के माध्यम से आउट-टू बाइट-डेटा प्राप्त करना।

एक आम संचार प्रक्रिया इस तरह दिखनी चाहिए:

  • जीपीएस डिवाइस मेरे सर्वर से एक कनेक्शन शुरू करता है
  • मेरा सर्वर जवाब अगर मैं डेटा प्राप्त करना चाहता हूँ
  • डिवाइस जीपीएस डेटा भेजें
  • मेरा सर्वर डिवाइस प्राप्त करने के बारे में रिपोर्ट भेजता है (एसआईजी जैसे चेकसम)
  • जीपीएस से नए डेटा प्राप्त करना, रिपोर्ट करें और यह बार-बार होता है
  • बाद में जीपीएस डिवाइस कनेक्शन बंद कर देता है

तो, मेरे सर्वर में मुझे इसकी आवश्यकता है

  • कनेक्टेड / सक्रिय क्लायंट ट्रेस करें
  • किसी भी क्लाइंट को सर्वर साइड से बंद करने के लिए
  • घटना को पकड़ो, जब कोई डिवाइस कनेक्शन बंद कर देता है
  • बाइट डेटा प्राप्त करें
  • ग्राहकों को डेटा भेजें

मैंने इंटरनेट पर इस विषय के बारे में पढ़ना शुरू कर दिया, लेकिन यह मेरे लिए एक दुःस्वप्न लगता है कई तरीके हैं, लेकिन मुझे पता नहीं था कि सबसे अच्छा कौन सा है।

Async सॉकेट विधियों मेरे लिए सबसे अच्छा लगता है, लेकिन इस async शैली में कोड लिखना भयानक है और डिबग करने में आसान नहीं है

तो मेरा सवाल है: सी # में उच्च प्रदर्शन टीसीपी सर्वर को लागू करने का सबसे अच्छा तरीका क्या है? क्या आप यह करने के लिए किसी भी अच्छा खुला स्रोत घटक जानते हैं? (मैंने कई लोगों की कोशिश की, लेकिन मुझे अच्छा नहीं मिला।)

Solutions Collecting From Web of "सी # में उच्च प्रदर्शन टीसीपी सर्वर"

यह एसिंक होना चाहिए, इसके आसपास कोई रास्ता नहीं है। उच्च प्रदर्शन और स्केलेबिलिटी एक धागा-प्रति-सॉकेट के साथ मिश्रण नहीं करते हैं आप खुद को देख सकते हैं कि स्टैकएक्सचेंज खुद क्या कर रहे हैं, एसिंक रेडिस बुकसलीव का इंतजार करें जो अगले सी # रिलीज से सीटीपी विशेषताओं का लाभ उठाते हैं (ऐसा किनारे पर है और बदलाव के अधीन है, लेकिन यह अच्छा है)। और अधिक खून बह रहा किनारे के लिए समाधान सॉकेट एसिंन्ट एवेंट क्लास के उत्थान के आसपास विकसित होते हैं जो 'क्लासिक' सी # एएससीएनसी प्रोसेसिंग से जुड़े एसिंक हैंडलर्स के लगातार आवंटन को समाप्त करके एक कदम आगे ले जाता है:

SocketAsyncEventArgs वर्ग System.Net.Sockets.Socket वर्ग के संवर्द्धन के एक हिस्से का हिस्सा है जो एक वैकल्पिक अतुल्यकालिक पैटर्न प्रदान करता है जिसका उपयोग विशेष उच्च-प्रदर्शन सॉकेट अनुप्रयोगों द्वारा किया जा सकता है। इस वर्ग को विशेष रूप से नेटवर्क सर्वर अनुप्रयोगों के लिए डिज़ाइन किया गया था, जिन्हें उच्च प्रदर्शन की आवश्यकता होती है। एक एप्लिकेशन बढ़ाया अतुल्यकालिक पैटर्न का विशेष रूप से या केवल लक्षित गर्म क्षेत्रों में उपयोग कर सकता है (उदाहरण के लिए, जब बड़ी मात्रा में डेटा प्राप्त होता है)

लंबी कहानी कम: async सीखना या कोशिश कर मरना …

बीटीडब्ल्यू, यदि आप पूछ रहे हैं कि क्यों async, तो इस पोस्ट से जुड़े तीन लेख पढ़ें: उच्च निष्पादन Windows प्रोग्राम अंतिम जवाब यह है कि अंतर्निहित ओएस डिजाइन की आवश्यकता है।

जैसा रीमस ऊपर बताता है, आपको प्रदर्शन उच्च रखने के लिए async का उपयोग करना होगा यही आरंभ है … / समाप्ति … विधियों में .NET।

कुर्सियों के लिए हुड के तहत, इन विधियों में आईओ समापन बंदरगाहों का उपयोग होता है जो कि विंडोज ऑपरेटिंग सिस्टम पर कई सॉकेट्स के प्रसंस्करण का सबसे शानदार तरीका लगता है।

जैसे जिम कहते हैं, TcpClient क्लास यहाँ मदद कर सकता है और उपयोग करने के लिए बहुत आसान है। यहां आने वाले कनेक्शनों और TcpClient को संभालने के लिए TcpListener का उपयोग करने का एक उदाहरण है, आरंभिक BeginAccept और BeginRead कॉल async होने के साथ,

यह उदाहरण मानता है कि एक संदेश आधारित प्रोटोकॉल सॉकेट्स पर इस्तेमाल किया जाता है और जो कि प्रत्येक संचरण के पहले 4 बाइट्स की लंबाई है, लेकिन इसके बावजूद यह बाकी है कि आप शेष डेटा प्राप्त करने के लिए स्ट्रीम पर एक तुल्यकालिक पढ़ें पढ़ें वह पहले से ही बफर है

यहां कोड है:

class ClientContext { public TcpClient Client; public Stream Stream; public byte[] Buffer = new byte[4]; public MemoryStream Message = new MemoryStream(); } class Program { static void OnMessageReceived(ClientContext context) { // process the message here } static void OnClientRead(IAsyncResult ar) { ClientContext context = ar.AsyncState as ClientContext; if (context == null) return; try { int read = context.Stream.EndRead(ar); context.Message.Write(context.Buffer, 0, read); int length = BitConverter.ToInt32(context.Buffer, 0); byte[] buffer = new byte[1024]; while (length > 0) { read = context.Stream.Read(buffer, 0, Math.Min(buffer.Length, length)); context.Message.Write(buffer, 0, read); length -= read; } OnMessageReceived(context); } catch (System.Exception) { context.Client.Close(); context.Stream.Dispose(); context.Message.Dispose(); context = null; } finally { if (context != null) context.Stream.BeginRead(context.Buffer, 0, context.Buffer.Length, OnClientRead, context); } } static void OnClientAccepted(IAsyncResult ar) { TcpListener listener = ar.AsyncState as TcpListener; if (listener == null) return; try { ClientContext context = new ClientContext(); context.Client = listener.EndAcceptTcpClient(ar); context.Stream = context.Client.GetStream(); context.Stream.BeginRead(context.Buffer, 0, context.Buffer.Length, OnClientRead, context); } finally { listener.BeginAcceptTcpClient(OnClientAccepted, listener); } } static void Main(string[] args) { TcpListener listener = new TcpListener(new IPEndPoint(IPAddress.Any, 20000)); listener.Start(); listener.BeginAcceptTcpClient(OnClientAccepted, listener); Console.Write("Press enter to exit..."); Console.ReadLine(); listener.Stop(); } } 

यह दर्शाता है कि कैसे async कॉल को संभालना है, लेकिन यह सुनिश्चित करने के लिए जोड़कर त्रुटि हैंडलिंग की आवश्यकता होगी कि TcpListener हमेशा नए कनेक्शन स्वीकार कर रहा है और क्लाइंट अनपेक्षित रूप से डिस्कनेक्ट करने के लिए अधिक त्रुटि हैंडलिंग इसके अलावा, वहाँ कुछ मामलों में प्रतीत नहीं होता है, जहां सभी डेटा एक ही समय में आने पर नहीं होता है, जिसके लिए भी निपटने की आवश्यकता होगी।

आप ऐसा टीसीपी क्लाइंट क्लास के साथ कर सकते हैं, हालांकि सच बताइए मुझे नहीं पता है कि आपके पास 10 हजार खुले सॉकेट हो सकते हैं। यह बहुत कुछ है लेकिन मैं नियमित रूप से समवर्ती सॉकेट्स के दर्जनों को संभालने के लिए नियमित रूप से TcpClient का उपयोग करता हूं। और एसिंक्रोनस मॉडल वास्तव में उपयोग करने के लिए बहुत अच्छा है।

आपकी सबसे बड़ी समस्या TcpClient काम करने वाला नहीं है। 10 हजार समवर्ती कनेक्शन के साथ, मैं बैंडविड्थ सोच रहा हूं और स्केलेबिलिटी समस्याएं होने जा रही हैं। मुझे यह भी पता नहीं है कि एक मशीन सभी यातायात को नियंत्रित कर सकती है। मुझे लगता है यह निर्भर करता है कि पैकेट कितने बड़े हैं और कितनी बार वे आ रहे हैं। लेकिन आप एक कंप्यूटर पर इन सभी को कार्यान्वित करने के लिए प्रतिबद्ध होने से पहले आप कुछ बैक-ऑफ-

मुझे लगता है कि आप यूडीपी तकनीकों के लिए भी देख रहे हैं। 10k ग्राहकों के लिए, यह तेज़ है, लेकिन आपको संदेश प्राप्त होने वाले प्रत्येक संदेश के लिए इस मुद्दे को लागू करना है। यूडीपी में आपको प्रत्येक ग्राहक के लिए सॉकेट खोलने की आवश्यकता नहीं है, लेकिन क्लाइंट कनेक्ट होने या नहीं करने के लिए एक्स सेकंड के बाद दिल की धड़कन / पिंग तंत्र को लागू करने की आवश्यकता है।

मेरे द्वारा किए गए मेरे टीसीपी सीएसएसआरपीएस सर्वर का उपयोग कर सकते हैं, इसे लागू करने के लिए बहुत आसान है, सिर्फ अपनी क्लासेस में से एक पर आईसीएलएन्टआरिवेस्ट लागू करें

 using System; using System.Collections.Generic; using System.Linq; namespace cSharpServer { public interface IClientRequest { /// <summary> /// this needs to be set, otherwise the server will not beable to handle the request. /// </summary> byte IdType { get; set; } // This is used for Execution. /// <summary> /// handle the process by the client. /// </summary> /// <param name="data"></param> /// <param name="client"></param> /// <returns></returns> byte[] Process(BinaryBuffer data, Client client); } } 

बाइनरीबफर आपको सर्वर को भेजे गए डेटा को वास्तव में आसान पढ़ने की अनुमति देता है।

 using System; using System.Collections.Generic; using System.Linq; using System.Runtime.CompilerServices; using System.Text; using System.Threading.Tasks; namespace cSharpServer { public class BinaryBuffer { private const string Str0001 = "You are at the End of File!"; private const string Str0002 = "You are Not Reading from the Buffer!"; private const string Str0003 = "You are Currenlty Writing to the Buffer!"; private const string Str0004 = "You are Currenlty Reading from the Buffer!"; private const string Str0005 = "You are Not Writing to the Buffer!"; private const string Str0006 = "You are trying to Reverse Seek, Unable to add a Negative value!"; private bool _inRead; private bool _inWrite; private List<byte> _newBytes; private int _pointer; public byte[] ByteBuffer; [MethodImpl(MethodImplOptions.AggressiveInlining)] public override string ToString() { return Helper.DefaultEncoding.GetString(ByteBuffer, 0, ByteBuffer.Length); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public BinaryBuffer(string data) : this(Helper.DefaultEncoding.GetBytes(data)) { } [MethodImpl(MethodImplOptions.AggressiveInlining)] public BinaryBuffer() { } [MethodImpl(MethodImplOptions.AggressiveInlining)] public BinaryBuffer(byte[] data) : this(ref data) { } [MethodImpl(MethodImplOptions.AggressiveInlining)] public BinaryBuffer(ref byte[] data) { ByteBuffer = data; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void IncrementPointer(int add) { if (add < 0) { throw new Exception(Str0006); } _pointer += add; if (EofBuffer()) { throw new Exception(Str0001); } } [MethodImpl(MethodImplOptions.AggressiveInlining)] public int GetPointer() { return _pointer; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static string GetString(ref byte[] buffer) { return Helper.DefaultEncoding.GetString(buffer, 0, buffer.Length); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static string GetString(byte[] buffer) { return GetString(ref buffer); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void BeginWrite() { if (_inRead) { throw new Exception(Str0004); } _inWrite = true; _newBytes = new List<byte>(); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Write(float value) { if (!_inWrite) { throw new Exception(Str0005); } _newBytes.AddRange(BitConverter.GetBytes(value)); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Write(byte value) { if (!_inWrite) { throw new Exception(Str0005); } _newBytes.Add(value); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Write(int value) { if (!_inWrite) { throw new Exception(Str0005); } _newBytes.AddRange(BitConverter.GetBytes(value)); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Write(long value) { if (!_inWrite) { throw new Exception(Str0005); } byte[] byteArray = new byte[8]; unsafe { fixed (byte* bytePointer = byteArray) { *((long*)bytePointer) = value; } } _newBytes.AddRange(byteArray); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public int UncommitedLength() { return _newBytes == null ? 0 : _newBytes.Count; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void WriteField(string value) { Write(value.Length); Write(value); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Write(string value) { if (!_inWrite) { throw new Exception(Str0005); } byte[] byteArray = Helper.DefaultEncoding.GetBytes(value); _newBytes.AddRange(byteArray); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Write(decimal value) { if (!_inWrite) { throw new Exception(Str0005); } int[] intArray = decimal.GetBits(value); Write(intArray[0]); Write(intArray[1]); Write(intArray[2]); Write(intArray[3]); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void SetInt(int value, int pos) { byte[] byteInt = BitConverter.GetBytes(value); for (int i = 0; i < byteInt.Length; i++) { _newBytes[pos + i] = byteInt[i]; } } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void SetLong(long value, int pos) { byte[] byteInt = BitConverter.GetBytes(value); for (int i = 0; i < byteInt.Length; i++) { _newBytes[pos + i] = byteInt[i]; } } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Write(byte[] value) { Write(ref value); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Write(ref byte[] value) { if (!_inWrite) { throw new Exception(Str0005); } _newBytes.AddRange(value); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void EndWrite() { if (ByteBuffer != null) { _newBytes.InsertRange(0, ByteBuffer); } ByteBuffer = _newBytes.ToArray(); _newBytes = null; _inWrite = false; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void EndRead() { _inRead = false; _pointer = 0; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void BeginRead() { if (_inWrite) { throw new Exception(Str0003); } _inRead = true; _pointer = 0; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public byte ReadByte() { if (!_inRead) { throw new Exception(Str0002); } if (EofBuffer()) { throw new Exception(Str0001); } return ByteBuffer[_pointer++]; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public int ReadInt() { if (!_inRead) { throw new Exception(Str0002); } if (EofBuffer(4)) { throw new Exception(Str0001); } int startPointer = _pointer; _pointer += 4; return BitConverter.ToInt32(ByteBuffer, startPointer); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public float[] ReadFloatArray() { float[] dataFloats = new float[ReadInt()]; for (int i = 0; i < dataFloats.Length; i++) { dataFloats[i] = ReadFloat(); } return dataFloats; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public float ReadFloat() { if (!_inRead) { throw new Exception(Str0002); } if (EofBuffer(sizeof(float))) { throw new Exception(Str0001); } int startPointer = _pointer; _pointer += sizeof(float); return BitConverter.ToSingle(ByteBuffer, startPointer); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public decimal ReadDecimal() { if (!_inRead) { throw new Exception(Str0002); } if (EofBuffer(16)) { throw new Exception(Str0001); } return new decimal(new[] { ReadInt(), ReadInt(), ReadInt(), ReadInt() }); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public long ReadLong() { if (!_inRead) { throw new Exception(Str0002); } if (EofBuffer(8)) { throw new Exception(Str0001); } int startPointer = _pointer; _pointer += 8; return BitConverter.ToInt64(ByteBuffer, startPointer); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public string ReadString(int size) { return Helper.DefaultEncoding.GetString(ReadByteArray(size), 0, size); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public byte[] ReadByteArray(int size) { if (!_inRead) { throw new Exception(Str0002); } if (EofBuffer(size)) { throw new Exception(Str0001); } byte[] newBuffer = new byte[size]; Array.Copy(ByteBuffer, _pointer, newBuffer, 0, size); _pointer += size; return newBuffer; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public bool EofBuffer(int over = 1) { return ByteBuffer == null || ((_pointer + over) > ByteBuffer.Length); } } } 

पूर्ण प्रोजेक्ट गिथहब CSharpServer पर है