2011-03-26 14 views
9

क्या मैं हल करने के लिए कोशिश कर रहा हूँ: एक Erlang टीसीपी सर्वर है कि एक विशिष्ट पोर्ट पर सुनता है (कोड बाहरी उन्मुख इंटरफ़ेस/एपीआई के कुछ प्रकार में होनी चाहिए) और प्रत्येक आवक कनेक्शन द्वारा नियंत्रित किया जाना चाहिए gen_server (यह भी gen_tcp:accept को gen_server के अंदर कोड किया जाना चाहिए), लेकिन मैं वास्तव में प्रारंभिक रूप से उन प्रक्रियाओं की पूर्वनिर्धारित संख्या को उत्पन्न नहीं करना चाहता जो आने वाले कनेक्शन को स्वीकार करते हैं)। क्या यह किसी भी तरह से संभव है?Erlang भेजे टीसीपी कनेक्शन स्वीकार गतिशील

उत्तर

8

आप एक स्थिर gen_server (या किसी अन्य प्रक्रिया) जो accept और हर बार जब आप एक कनेक्शन लेने, एक कार्यकर्ता gen_server के अंडे देने के लिए एक पर्यवेक्षक बता का उपयोग कर इनकमिंग कनेक्शन के लिए सुनता होना चाहिए। इस प्रक्रिया के लिए पिड प्राप्त करें, उस पिड के साथ gen_tcp:controlling_process/2 पर कॉल करें और फिर उस प्रक्रिया में accept से प्राप्त सॉकेट भेजें (आप उस क्रम में ऐसा करें, अन्यथा नई प्रक्रिया सॉकेट का उपयोग करने से पहले सॉकेट का उपयोग कर सकती है) ।

सुन प्रक्रिया केवल एक ही जिम्मेदारी होनी चाहिए, और है कि नए कनेक्शन के लिए सुन रहा है। इसके कारण, इससे कोई फर्क नहीं पड़ता कि यह ब्लॉक करता है, इसलिए यह gen_server या कोई अन्य प्रक्रिया हो सकती है। असल में, यह शायद gen_server के रूप में होने के लिए अधिक है, यह बदले में एक नंगे-हड्डी proc_lib प्रक्रिया शुरू करना आसान और तेज़ होगा।

+0

धन्यवाद, मैं इस दृष्टिकोण को आजमाऊंगा क्योंकि यह सबसे व्यवहार्य लगता है – hyperboreean

4

gen_tcp:accept के साथ समस्या यह है कि यह ब्लॉक करता है, इसलिए यदि आप इसे gen_server में कॉल करते हैं, तो आप सर्वर को अन्य संदेशों को प्राप्त करने से रोकते हैं। आप टाइमआउट पास करके इसे टालने का प्रयास कर सकते हैं, लेकिन आखिरकार मतदान के एक रूप में वह राशि है जो सर्वोत्तम रूप से टाल जाती है। इसके बजाय, आप इसके बजाय Kevin Smith's gen_nb_server आज़मा सकते हैं; यह ब्लॉकिंग से बचने के लिए एक आंतरिक अनियंत्रित फ़ंक्शन prim_inet:async_accept और अन्य prim_inet फ़ंक्शंस का उपयोग करता है।

+0

लेकिन अगर मैं 'gen_tcp रिले करने के लिए एक तरह से यह पता लगाने कर सकते हैं: अपने स्वयं के gen_server में accept' की तुलना में मैं परवाह नहीं करता कि यह अवरोधित कर रही है। लेकिन मुझे लगता है कि आगे जानना संभव नहीं है ('gen_tcp: listen' से कहें) कि आपके पास एक आने वाला कनेक्शन है जिसे आपको स्वीकार करना है। पॉइंटर के लिए 'gen_nb_server' के लिए धन्यवाद! क्या आपने इसे उत्पादन में इस्तेमाल किया है? – hyperboreean

+0

मुझे नहीं लगता कि आपको जो भी कर रहा है उसके लिए आपको 'gen_nb_server' की आवश्यकता है। आपका मामला वास्तव में एक साधारण है। –

+1

मैंने कभी भी उत्पादन में 'gen_nb_server' का उपयोग नहीं किया है, लेकिन उत्पादन में 'prim_inet: async_accept' का उपयोग किया है। –

1

आप का उपयोग करना चाहिए "prim_inet: async_accept (Listen_socket, -1)" के रूप में स्टीव से कहा। अब भेजे कनेक्शन अपने handle_info कॉलबैक द्वारा स्वीकार कर लिया जाएगा (एक gen_server मानते हुए कि आपके इंटरफेस भी है) के रूप में आप एक अतुल्यकालिक कॉल स्वीकार इस्तेमाल किया है।

कनेक्शन यदि आप किसी अन्य ger_server अंडे कर सकते हैं स्वीकार करने पर (मैं gen_fsm सिफारिश करेंगे) और कहा कि "को नियंत्रित करने की प्रक्रिया" के रूप में बनाने के लिए बुला द्वारा "gen_tcp: controlling_process (CliSocket, spwned के PID)"।

इस के बाद सॉकेट से सभी डेटा है कि इस प्रक्रिया बजाय अपने इंटरफेस कोड द्वारा द्वारा प्राप्त किया जाएगा। इस तरह एक नई नियंत्रण प्रक्रिया किसी अन्य कनेक्शन के लिए तैयार की जाएगी।

+0

एट्रिब्यूशन के बिना कहीं और कट और पेस्ट करें। –

+0

हां मैंने इसे अपने स्वयं के एरलांग एप्लिकेशन से काट दिया है और चिपकाया है। क्या मुझे इसके लिए खुद से अनुमति लेने की ज़रूरत है? – Arunmu

+1

क्षमा करें, यह पहली बार देखने पर एक मेलिंग सूची संवाद से कुछ खंड की तरह लग रहा था। –

3

आप http://github.com/oscarh/gen_tcpd को देखना चाहेंगे और हैंडल_कनेक्शन फ़ंक्शन का उपयोग उस प्रक्रिया को कनवर्ट करने के लिए करें जो आप gen_server पर प्राप्त करते हैं।

संबंधित मुद्दे