سؤال

لدي برنامج python يستخدم حاليًا وحدة عميل tcp/ip التي كتبتها لتلقي البيانات من خادم البث.يقوم الخادم بإخراج أسطر من البيانات.

تعتبر فئة عميل TCP الخاصة بي بدائية إلى حد ما وأريد إعادة البناء لاستخدام ReconnectingClientFactory الملتوي.

يحصل البرنامج الرئيسي حاليًا على البيانات من وظيفة readLines في عميل TCP الخاص بي والتي "تنتج" الخطوط عند استلامها.

يتم الوصول إلى طريقة عميل TCP عن طريق:

for msg_buffer in self.myTcpClient.readLines():
    do some stuff with the data in msg_buffer

في عميل TCP الخاص بي، تبدو طريقة readLines في جوهرها كما يلي:

while True:
    newLine = self.sock.recv(self.buffer_size)
    yield newLine

عندما أقوم بتنفيذ العميل الملتوي، أريد طريقة ما ليعمل كمكرر وينتج البيانات.أفترض أنني سأفعل شيئًا ما في طريقة بروتوكول dataReceived.

لقد ضاعت وأنا أحاول معرفة كيف يعمل هذا.يبدو لي أن المؤجل الملتوي مخصص لهذا النوع من الاستخدام ولكن لا يمكنني معرفة كيفية استخدام المؤجل لغرضي (إذا كان افتراضي بشأن المؤجل صحيحًا).

في عالم مثالي، سيعطي العميل الملتوي الخطوط كما تم استلامها، لذا فإن مكالمة مشابهة للطريقة الحالية ستؤدي المهمة.أي.

class GetData(protocol):
    def dataReceived(self, data):
        yield data

لكنني أعتقد أن هذا تبسيط مبالغ فيه.

باختصار، ما أحاول القيام به هو تنفيذ عميل TCP لإعادة الاتصال الملتوي والذي يتصرف بطريقة تشبه طريقة readLines الخاصة بي ويمكن الوصول إليه بشكل أو بآخر مثل:

for msg_buffer in self.twistedTcpClient.readLines():

أي مؤشرات سيكون موضع تقدير كبير

تحديث:لقد تعثرت للتو عبر "الكروشيه" بسبب الملتوية.للوهلة الأولى، يبدو أن الكروشيه قد تم تصميمه خصيصًا لنوع النموذج الذي أحتاجه...سأقدم تقريرا بعد بعض الاختبارات

هل كانت مفيدة؟

المحلول

الطريقة الملتوية للقيام بذلك هي كتابة بروتوكول.بدلاً من القيام بما يلي:

for line in self.twistedTcpClient.readLines():
    process_line(line) ...

ستكتب البروتوكول الخاص بك (ربما عن طريق التصنيف الفرعي a twisted.protocols.basic.LineReceiver):

class MyProtocol(LineReceiver):
    ...
    def lineReceived(self, line):
        process_line(line) ...

تريد إعادة بناء التعليمات البرمجية الخاصة بك لاستخدام lineReceived رد الاتصال بدلاً من وجود حلقة متكررة.

ما كتبته:

for line in self.twistedTcpClient.readLines():
    process_line(line) ...

يمثل مشكلة لأن Twisted غير متزامن.لا توجد طريقة لـ Twisted للقيام بأي شيء آخر أثناء الانتظار twistedTcpClient.readLines() طريقة.

أقترح كتابة بروتوكول، ولكن إذا كنت تصر حقًا على وجود نمط التكرار هذا، فقد تتمكن من القيام بذلك:

@inlineCallbacks
def my_func():
    while True:
        try:
            line = yield self.twistedTcpClient.getNextLine()
        except StopIteration:
            break

        process_line(line) ...

الآن، الشيء الصعب هو صنعه twistedTcpClient يعود Deferreds لكل مكالمة إلى getNextLine().ربما شيء من هذا القبيل:

class MyProtocol(LineReceiver):
    ...
    def getNextLine(self):
        self.defer_given_out = Deferred()

    def lineReceived(self, line):
        self.defer_given_out.callback(line)

    def connectionLost(self):
        self.defer_given_out.errback(StopIteration())

(هذا مجرد مثال يوضح الفكرة، وسيتعين عليك توسيعه للتعامل مع التفاصيل.)

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top