ट्विस्ट काफी हर संभव तरीके से बेहतर है। यह अधिक पोर्टेबल, अधिक फीचर, सरल, अधिक स्केलेबल, बेहतर बनाए रखा, बेहतर दस्तावेज है, और यह एक स्वादिष्ट आमलेट बना सकता है। Asyncore, सभी उद्देश्यों और उद्देश्यों के लिए, अप्रचलित है।
यह सब तरीकों से मुड़ एक संक्षिप्त उत्तर में बेहतर है (मैं कैसे एक छोटी उदाहरण में एक http/dns/ssh/smtp/pop/imap/irc/xmpp/process-spawning/multi-threading सर्वर प्रदर्शन कर सकता?) प्रदर्शित करने के लिए मुश्किल है, इसलिए बजाय मैं लोगों को सबसे आम गलत धारणाओं पर ध्यान केंद्रित किया जाएगा जो लोगों को मुड़ने के बारे में लगता है: यह एसिंककोर से कहीं अधिक जटिल या कठिन है।
चलो एक एसिंककोर उदाहरण के साथ शुरू करते हैं। पक्षपातपूर्ण प्रस्तुति से बचने के लिए, मैं किसी और से एक उदाहरण का उपयोग करूंगा जो अभी भी थोड़ा सा एसिंककोर पसंद करता है। यहां एक सरल एसिंककोर उदाहरण taken from Richard Jones' weblog है (ब्रेवटी के लिए टिप्पणियों के साथ)।
सबसे पहले, यहाँ सर्वर है:
import asyncore, socket
class Server(asyncore.dispatcher):
def __init__(self, host, port):
asyncore.dispatcher.__init__(self)
self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
self.bind(('', port))
self.listen(1)
def handle_accept(self):
socket, address = self.accept()
print 'Connection by', address
EchoHandler(socket)
class EchoHandler(asyncore.dispatcher_with_send):
def handle_read(self):
self.out_buffer = self.recv(1024)
if not self.out_buffer:
self.close()
s = Server('', 5007)
asyncore.loop()
और यहां ग्राहक है:
import asyncore, socket
class Client(asyncore.dispatcher_with_send):
def __init__(self, host, port, message):
asyncore.dispatcher.__init__(self)
self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
self.connect((host, port))
self.out_buffer = message
def handle_close(self):
self.close()
def handle_read(self):
print 'Received', self.recv(1024)
self.close()
c = Client('', 5007, 'Hello, world')
asyncore.loop()
में कुछ अस्पष्ट मामलों है कि इस कोड सही तरीके से हैंडल नहीं करता हैं, लेकिन उन्हें समझा उबाऊ है और जटिल, और कोड पहले ही इस उत्तर को काफी लंबा बना चुका है।
अब, यहां कुछ कोड है जो मूल रूप से एक ही चीज़ है, ट्विस्ट के साथ। सबसे पहले, सर्वर:
from twisted.internet import reactor, protocol as p
class Echo(p.Protocol):
def dataReceived(self, data):
self.transport.write(data)
class EchoFactory(p.Factory):
def buildProtocol(self, addr):
print 'Connection by', addr
return Echo()
reactor.listenTCP(5007, EchoFactory())
reactor.run()
और अब, ग्राहक:
from twisted.internet import reactor, protocol as p
class EchoClient(p.Protocol):
def connectionMade(self):
self.transport.write(self.factory.data)
def dataReceived(self, data):
print 'Received:', data
self.transport.loseConnection()
class EchoClientFactory(p.ClientFactory):
protocol = EchoClient
def __init__(self, data):
self.data = data
reactor.connectTCP('localhost', 5007, EchoClientFactory('Hello, world'))
reactor.run()
चीजें हैं जो मैं आपका ध्यान आकर्षित करना चाहते हैं के एक जोड़े हैं। सबसे पहले, मुड़कर उदाहरण 25% छोटा है, यहां तक कि इस छोटे से कुछ के लिए भी। Asyncore के लिए 40 लाइनें, मुड़ के लिए केवल 30। चूंकि आपका प्रोटोकॉल अधिक जटिल हो जाता है, यह अंतर बड़ा और बड़ा हो जाएगा, क्योंकि आपको एसिंककोर के लिए अधिक से अधिक समर्थन कोड लिखना होगा जो आपके लिए मुड़कर प्रदान किया गया होगा।
दूसरा, ट्विस्ट पूर्ण अमूर्त प्रदान करता है। एसिंककोर उदाहरण के साथ, आपको वास्तविक नेटवर्किंग करने के लिए socket
मॉड्यूल का उपयोग करना होगा; Asyncore केवल मल्टीप्लेक्सिंग प्रदान करता है। यदि आपको portable behavior on platforms such as Windows की आवश्यकता है तो यह एक समस्या है। इसका मतलब यह भी है कि एसिंककोर में अन्य प्लेटफार्मों पर एसिंक्रोनस उप-प्रक्रिया संचार करने के लिए सुविधाओं की पूरी कमी नहीं है; आप मनमाने ढंग से फाइल डिस्क्रिप्टर को select()
विंडोज़ पर कॉल नहीं कर सकते हैं।
तीसरा, ट्विस्ट उदाहरण परिवहन तटस्थ है। Echo
और EchoFactory
और EchoClient
और EchoClientFactory
में से कोई भी किसी भी तरह से टीसीपी के लिए विशिष्ट नहीं है। आप इन कक्षाओं को पुस्तकालय में बना सकते हैं जिसे एसएसएच, या एसएसएल, या यूनिक्स सॉकेट, या पाइप के माध्यम से जोड़ा जा सकता है, केवल नीचे एक connectTCP
/listenTCP
कॉल को बदलकर। यह महत्वपूर्ण है, क्योंकि आपके प्रोटोकॉल तर्क में सीधे टीएलएस जैसे कुछ का समर्थन करना बहुत मुश्किल है। उदाहरण के लिए, टीएलएस में 'लिखना' निम्न स्तर पर 'पढ़ा' ट्रिगर करेगा। इसलिए, आपको इन चिंताओं को सही करने के लिए उन्हें अलग करने की आवश्यकता है।
अंत में, आपके उपयोग-मामले के लिए विशिष्ट, यदि आप सीधे मैक पते और ईथरनेट फ्रेम से निपट रहे हैं, तो ट्विस्ट में Twisted Pair, आईपी और ईथरनेट-स्तरीय नेटवर्किंग से निपटने के लिए निम्न स्तर की लाइब्रेरी है। यह मुड़ने का सबसे सक्रिय रूप से बनाए रखा हिस्सा नहीं है; कोड काफी पुराना है। लेकिन, यह काम करना चाहिए, और अगर ऐसा नहीं होता है तो हम इसमें कोई भी बग गंभीरता से लेंगे और (अंततः) देखेंगे कि वे तय हो गए हैं। जहां तक मुझे पता है, एसिंककोर के लिए कोई तुलनात्मक लाइब्रेरी नहीं है, और इसमें निश्चित रूप से ऐसा कोई कोड नहीं है।
क्यों -1? ... –
asyncore/asynchat केवल सॉकेट हैंडलिंग में बंधे होने पर ही उपयोगी होता प्रतीत होता है।मेरे कोड में, 'स्निफर' सभी सॉकेट सामान को संभालता है और परिणाम उत्पन्न करता है। मैं चाहता हूं कि एसिंककोर करना मेरा 'पहला' और 'दूसरा' फ़ंक्शंस चलाएं और मुझे 'स्निफर' रिटर्न डेटा के दौरान कॉलबैक जारी करने दें। यह मैं कैसे करूंगा? (मैंने आपको डाउनवोट नहीं किया है, बीटीडब्ल्यू) – dave
एसिंककोर/एसिन्चैट आपको 'चयन' फ़ंक्शन कॉल के आसपास ऑब्जेक्ट ओरिएंटेड रैपर देता है (जो आम तौर पर सभी एसिंक चीजें बनती हैं)। 'select' फ़ाइल डिस्क्रिप्टर पर चल रहा है, इसलिए यह भी है कि asyncore/asynchat भी करता है। मेरे लिए कुछ काम करने योग्य बनाने के लिए मुझे कुछ मिनट दें। –