2008-09-13 8 views
14

मैं बेसहॉट में एक छोटा वेब सर्वर लिख रहा हूं, बेसएचटीटीपीएसरवर और बेसएचटीटीपीएसरवर का एक कस्टम उप-वर्ग। बेसहेटीपीआरक्वैस्ट हैंडलर। क्या यह एक से अधिक बंदरगाहों पर सुनना संभव है?एकाधिक बंदरगाहों को सुनने के लिए मैं एक पायथन HTTP सर्वर कैसे लिखूं?

क्या मैं अब कर रहा हूँ:

class MyRequestHandler(BaseHTTPServer.BaseHTTPRequestHandler): 
    def doGET 
    [...] 

class ThreadingHTTPServer(ThreadingMixIn, HTTPServer): 
    pass 

server = ThreadingHTTPServer(('localhost', 80), MyRequestHandler) 
server.serve_forever() 

उत्तर

28

ज़रूर; दो अलग-अलग बंदरगाहों पर दो अलग-अलग बंदरगाहों पर दो अलग-अलग सर्वरों को शुरू करें जो प्रत्येक एक ही हैंडलर का उपयोग करते हैं। यहां एक पूर्ण, कामकाजी उदाहरण है जिसे मैंने अभी लिखा और परीक्षण किया। आप इस कोड को चलाने के हैं तो आप http://localhost:1111/ और http://localhost:2222/

from threading import Thread 
from SocketServer import ThreadingMixIn 
from BaseHTTPServer import HTTPServer, BaseHTTPRequestHandler 

class Handler(BaseHTTPRequestHandler): 
    def do_GET(self): 
     self.send_response(200) 
     self.send_header("Content-type", "text/plain") 
     self.end_headers() 
     self.wfile.write("Hello World!") 

class ThreadingHTTPServer(ThreadingMixIn, HTTPServer): 
    pass 

def serve_on_port(port): 
    server = ThreadingHTTPServer(("localhost",port), Handler) 
    server.serve_forever() 

Thread(target=serve_on_port, args=[1111]).start() 
serve_on_port(2222) 
+0

क्या यह जीआईएल के साथ ठीक है? – sashab

+1

@scrat: जीआईएल इस कोड के लिए ज्यादा मायने रखता नहीं है, क्योंकि यह कोड अधिकतर I/o बाध्य होगा, और पायथन में अधिकांश I/O निम्न स्तर के सी पुस्तकालयों का उपयोग करके लिखा जाता है जो जीआईएल जारी करते हैं। अधिकांश प्रदर्शन प्रश्नों के साथ, मेरी सलाह है कि आप इसके बारे में चिंता न करें जबतक कि आपने अपना कोड बेंचमार्क नहीं किया है और यह निर्धारित किया है कि यह वास्तव में एक समस्या है। मानक पुस्तकालय में चिपकने के लिए –

+0

+1 :) –

4

नहीं आसानी से दोनों पर एक नमस्ते विश्व वेबपेज प्राप्त करने में सक्षम हो जाएगा। आपके पास दो थ्रेडिंग एचटीटीपीएस सर्वर उदाहरण हो सकते हैं, अपना स्वयं का Serv_forever() फ़ंक्शन लिखें (चिंता न करें यह एक जटिल कार्य नहीं है)।

मौजूदा समारोह:

def serve_forever(self, poll_interval=0.5): 
    """Handle one request at a time until shutdown. 

    Polls for shutdown every poll_interval seconds. Ignores 
    self.timeout. If you need to do periodic tasks, do them in 
    another thread. 
    """ 
    self.__serving = True 
    self.__is_shut_down.clear() 
    while self.__serving: 
     # XXX: Consider using another file descriptor or 
     # connecting to the socket to wake this up instead of 
     # polling. Polling reduces our responsiveness to a 
     # shutdown request and wastes cpu at all other times. 
     r, w, e = select.select([self], [], [], poll_interval) 
     if r: 
      self._handle_request_noblock() 
    self.__is_shut_down.set() 

इसलिए हमारे प्रतिस्थापन होगा कुछ की तरह:

def serve_forever(server1,server2): 
    while True: 
     r,w,e = select.select([server1,server2],[],[],0) 
     if server1 in r: 
      server1.handle_request() 
     if server2 in r: 
      server2.handle_request() 
6

मैं कहूँगा कि कुछ इस सरल के लिए सूत्रण overkill है। आप असीमित प्रोग्रामिंग के कुछ रूपों का उपयोग कर बेहतर हैं।

यहाँ एक उदाहरण Twisted उपयोग कर रहा है:

from twisted.internet import reactor 
from twisted.web import resource, server 

class MyResource(resource.Resource): 
    isLeaf = True 
    def render_GET(self, request): 
     return 'gotten' 

site = server.Site(MyResource()) 

reactor.listenTCP(8000, site) 
reactor.listenTCP(8001, site) 
reactor.run() 

मैं भी सोचता है कि यह प्रत्येक बंदरगाह के बजाय मुख्य थ्रेड एक बंदरगाह और एक अतिरिक्त धागा संभाल होने के, एक ही तरह से नियंत्रित किया जाना है करने के लिए एक बहुत क्लीनर लग रहा है दूसरे को संभालें। तर्कसंगत है कि थ्रेड उदाहरण में तय किया जा सकता है, लेकिन फिर आप तीन धागे का उपयोग कर रहे हैं।

+0

आप कुछ बहुत अच्छे अंक बनाते हैं, और मैं अपने जवाब में ट्विस्ट का उपयोग करने की सलाह देने के लिए प्रेरित था। मेरे दृष्टिकोण का मुख्य लाभ यह है कि इसे मानक पुस्तकालय के बाहर कुछ भी नहीं चाहिए। एक असली एप्लिकेशन के लिए मैं अपाचे के पीछे चेरीपी का उपयोग करता हूं या कुछ और जो बेसएचटीटीपीएसवर नहीं है। –

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