Хороший способ написать облегченную клиентскую функцию для импорта Twisted Python - PullRequest
2 голосов
/ 10 сентября 2009

У меня работает следующий сервер:

class ThasherProtocol(basic.LineReceiver):
    def lineReceived(self, line):
        dic = simplejson.loads( line)
        ret = self.factory.d[ dic['method'] ]( dic['args'] )
        self.transport.write( simplejson.dumps( ret) )
        self.transport.loseConnection()



class ThasherFactory(ServerFactory):
    protocol = ThasherProtocol 

    def __init__(self):
        self.thasher = Thasher()
        self.d= {   
            'getHash': self.thasher.getHash,
            'sellHash' : self.thasher.sellHash
            }


reactor.listenUNIX( c.LOCATION_THASHER, ThasherFactory() )
reactor.run()

У меня есть несколько файлов, импортирующих специальную функцию getHash из определенного файла. Обратите внимание, что аргументы getHash будут только словарем текстов (строк). Как мне написать клиентскую функцию (getHash), которая может быть просто:

from particular file import getHash
i = getHash( { 'type':'url', 'url':'http://www.stackoverflow.com' } )

Обратите внимание, что все, что я хочу сделать, это: 1) выбросить диктат в json, 2) сбросить этот JSON в конкретный сокет, 3) подождите, пока он вернется и распакуйте json

Ответы [ 2 ]

2 голосов
/ 10 сентября 2009

Вы хотите, чтобы getHash вернул Deferred, а не синхронное значение.

Способ сделать это - создать Deferred и связать его с соединением, которое выполняет определенный запрос.

Следующее не проверено и, вероятно, не будет работать, но оно должно дать вам приблизительное представление:

import simplejson
from twisted.python.protocol import ClientFactory
from twisted.internet.defer import Deferred
from twisted.internet import reactor
from twisted.protocols.basic import LineReceiver

class BufferingJSONRequest(LineReceiver):
    buf = ''

    def connectionMade(self):
        self.sendLine(simplejson.dumps(self.factory.params))

    def dataReceived(self, data):
        self.buf += data

    def connectionLost(self, reason):
        deferred = self.factory.deferred
        try:
            result = simplejson.load(self.buf)
        except:
            deferred.errback()
        else:
            deferred.callback(result)

class BufferingRequestFactory(ClientFactory):
    protocol = BufferingJSONRequest

    def __init__(self, params, deferred):
        self.params = params
        self.deferred = deferred

    def clientConnectionFailed(self, connector, reason):
        self.deferred.errback(reason)

def getHash(params):
    result = Deferred()
    reactor.connectUNIX(LOCATION_THASHER,
                        BufferingRequestFactory(params, result))
    return result

Теперь, чтобы использовать эту функцию, вам уже нужно быть знакомым с Deferreds, и вам нужно будет написать функцию обратного вызова, которая будет запускаться, когда в конечном итоге придет результат. Но объяснение тому принадлежит отдельному вопросу;).

0 голосов
/ 10 сентября 2009

Мне удалось решить собственную проблему.

Использование сокетов (в частности, Unix-сокетов) ускоряет мое приложение в 4 раза, и его совсем не сложно использовать.

так что теперь мое решение - просто json + socket

...