2012-05-28 15 views
6

पर भेजना मैं एचटीएमएल 5 वेबसाकेट्स का उपयोग करना सीख रहा हूं और इसके हिस्से के रूप में मैं पाइथन में एक सर्वर लिख रहा हूं, इसलिए मैं जान सकता हूं कि वे कैसे काम करते हैं। मैंने एक और दिन बनाया जो बहुत अच्छी तरह से काम करता था, लेकिन मैं इसे विस्तारित करना चाहता था ताकि यह प्रत्येक एंडपॉइंट के साथ एक अलग "सेवा" होने के साथ कई अंतराल का समर्थन करे जो वेबसाईट क्लाइंट को संभाल सके।सॉकेट ऑब्जेक्ट को फोर्कड रनिंग प्रक्रिया (मल्टीप्रोसेसिंग.क्यूयू)

फिलहाल, मेरा कार्यान्वयन स्पॉन्गिंग प्रक्रियाओं के साथ काम करता है और इस तरह (मैं थ्रेडिंग के बजाय मल्टीप्रोसेसिंग का उपयोग कर रहा हूं क्योंकि मैंने पढ़ा है कि थ्रेडिंग वास्तव में सीपीथॉन में बहुसंख्यक नहीं है और यही मुझे लगता है कि मैं उपयोग कर रहा हूं (उबंटू 12.04 पर डिफ़ॉल्ट इंस्टॉल)), लेकिन मुझे सेवा प्रक्रियाओं में प्राप्त क्लाइंट सॉकेट भेजने में परेशानी हो रही है।

यहाँ कैसे मैं उन्हें भेजने के लिए (यह एक पाश में चलता है) है:

try: 
    #get a new client 
    conn, addr = server.accept() 
    print "Client connected from", addr 
    request = conn.recv(4096) 
    response, close, service = self.handshake(request) 
    conn.send(response) 
    if close: 
     print "Invalid request from", addr 
     conn.close() 
     continue 
    client = WebSockets.WebSocketClient(conn, addr) 
    service.clientConnQueue.put(client) 

'सर्वर' एक सॉकेट इनकमिंग कनेक्शन के लिए सुन रहा है। हैंडशेक विधि उनके अनुरोध को सत्यापित करने और क्लाइंट को रखने के लिए कौन सी सेवा प्रक्रिया निर्धारित करने का ख्याल रखती है। 'प्रतिक्रिया' भेजने के लिए http प्रतिक्रिया है, अगर कोई त्रुटि हुई, तो 'बंद' सत्य है, और 'सेवा' एक वर्ग है जो मल्टीप्रोसेसिंग से प्राप्त होती है। क्यूयू। WebSocktes.WebSocketClient वह जगह है जहां मेरा भेजने और प्राप्त करने का कार्यान्वयन संग्रहीत किया जाता है और यह मूल रूप से सॉकेट के लिए एक रैपर के रूप में कार्य करता है।

'clientConnQueue' इसलिए की तरह बनाई गई है:

class Service(multiprocessing.Process): 
    """Base class for all services.""" 
    def __init__(self, manager): 
     multiprocessing.Process.__init__(self) 
     self.manager = manager 
     self.clientConnQueue = self.manager.Queue() 
     self.shutdownFlag = multiprocessing.Event() 

प्रबंधक एक multiprocessing.Manager()

त्रुटि मैं जब मैं इस प्रकार एक ग्राहक जगह में clientConnQueue है की कोशिश है:

File "./WebSocketServer.py", line 183, in <module> 
main() 
File "./WebSocketServer.py", line 180, in main 
server.runServer() 
File "./WebSocketServer.py", line 67, in runServer 
service.clientConnQueue.put(client) 
File "<string>", line 2, in put 
File "/usr/lib/python2.7/multiprocessing/managers.py", line 758, in _callmethod 
conn.send((self._id, methodname, args, kwds)) 
TypeError: expected string or Unicode object, NoneType found 

मुझे प्राप्त करने वाले पक्ष पर एक टूटी पाइप त्रुटि मिलती है।

मुझे एक ही त्रुटि मिली जब मैं एक मल्टीप्रोसेसिंग का उपयोग कर रहा था। कनेक्शन भेजने के लिए और मैंने सोचा कि प्रबंधक द्वारा बनाई गई कतार में इसे बदलने से समस्या ठीक हो जाएगी। हालांकि, ऐसा लगता है कि यह वही कार्यान्वयन करता है।

स्पष्ट रूप से ऐसा कोई तरीका नहीं है कि किसी को चलने की प्रक्रिया में ऐसा कुछ भेजना है, तो प्रक्रिया में गैर-धारावाहिक वस्तुओं को भेजने का उचित तरीका क्या है?

उत्तर

1

दूसरी प्रक्रिया में पास सॉकेट एक छोटी सी चीज नहीं है। देखो, उदाहरण के लिए, यह प्रश्न: Can I open a socket and pass it to another process in Linux

वैसे भी, ओएस प्रक्रिया या धागे आप वास्तव में वेब मेमोरी सर्वर को लागू करने के लिए नहीं चाहते हैं, क्योंकि बड़ी मेमोरी ओवरहेड है। नॉनब्लॉकिंग सॉकेट के साथ smth देखो ...उदाहरण के लिए, टोरनाडो http://www.tornadoweb.org/documentation/websocket.html

+1

प्रत्येक क्लाइंट सॉकेट को अपना स्वयं का धागा नहीं मिलना चाहिए, लेकिन प्रत्येक सेवा को अपनी प्रक्रिया/धागा मिल जाता है और यह सॉकेट के साथ क्या करना है, यह सेवा के लिए छोड़ दिया जाता है। हालांकि यह एक अच्छा मुद्दा है ... http सर्वरों को 1000 एक साथ लंबे समय तक रहने वाले कनेक्शन की संभावना से निपटने की ज़रूरत नहीं है और यदि प्रत्येक कनेक्शन का अपना धागा होता है तो यह बहुत मेमोरी ओवरहेड होता है। –

0

आप गहरे यूनिक्स जादू का उपयोग किये बिना फोर्क प्रक्रियाओं के लिए सॉकेट नहीं भेज सकते हैं। आप यूनिक्स पर्यावरण में उन्नत प्रोग्रामिंग पुस्तक पढ़ सकते हैं यदि आप वास्तव में देखना चाहते हैं कि यह सी

थ्रेडिंग का उपयोग करने के लिए एक आसान समाधान परिवर्तन के लिए और आपका कोड शायद काम करेगा। जबकि पाइथन में थ्रेडिंग सही नहीं है, यह आईओ गहन सामग्री करने के लिए बहुत अच्छा है।

वैकल्पिक रूप से फोर्किंग से पहले अपनी सुनवाई सॉकेट बनाएं और सुनने के लिए सभी उपप्रोसेस प्राप्त करें (accept पर कॉल करें)। ओएस यह सुनिश्चित करेगा कि उनमें से केवल एक कनेक्शन हो। इस तरह से preforking सर्वर आमतौर पर लिखा जाता है।

1

यह 4+ वर्षों के आसपास रहा है, हालांकि थोड़ा सा काम लगता है।

मल्टीप्रोसेसिंग.डक्शन में गड़गड़ाहट लटक रही है, और उदाहरण के विवरण this github gist में देखे जा सकते हैं।

0

यदि आप प्रक्रिया फोर्किंग से पहले सॉकेट बनाते हैं, तो इसके फ़ाइल डिस्क्रिप्टर को बच्चों द्वारा विरासत में प्राप्त किया जाएगा।

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