Bienvenue sur IndexError.

Ici vous pouvez poser des questions sur Python et le Framework Django.

Consultez la FAQ pour améliorer vos chances d'avoir des réponses à vos questions.

Crossbar.io : effectuer un call dans une procédure

+3 votes

Je travaille avec crossbar.io et souhaiterais, dans une fonction enregistrée comme procédure, effectuer un call. J'ai donc un truc du genre :

from twisted.internet.defer import inlineCallbacks

from autobahn import wamp
from autobahn.twisted.wamp import ApplicationSession

from globals.topics import TOPICS


class AbstractLocator(ApplicationSession):

    def __init__(self, config):
           ApplicationSession.__init__(self, config)

    @inlineCallbacks
    def onJoin(self, details):
        reg = yield self.register(self)
        print("{} procedures registered from AbstractLocator.".format(len(reg)))

    sub = yield self.subscribe(self)
    print("{} topics subscribed to from AbstractLocator.".format(len(sub)))

    @wamp.register(TOPICS.move)
    def moveReg(self):
        res = self.call(TOPICS.coverArea, arg1, arg2)
        return res

 

Seulement, j'obtiens l'erreur : autobahn.wamp.exception.SerializationError: Unable to serialize WAMP application payload ( is not JSON serializable)

 

Si je rajoute un yield devant le self.call, l'erreur devient : autobahn.wamp.exception.SerializationError: Unable to serialize WAMP application payload ( is not JSON serializable)

 

Cela provient-il de ma façon d'utiliser call ? D'autre chose ?

demandé 1-Jan-2015 par Vayel (1,058 points)
edité 12-Jan-2015 par foxmask
Inutile de mettre "hello", "merci", etc. Juste la question suffit. Ca permet d'aller droit au but.

1 Réponse

+5 votes
 
Meilleure réponse

J'ai pas ton code pour tester, mais à vu de nez :

from twisted.internet.defer import returnValue

@wamp.register(TOPICS.move)
@inlineCallback
def moveReg(self):
    res = yield self.call(TOPICS.coverArea, arg1, arg2)
    returnValue(res)

Car self.call est asynchrone, donc retourne un defer.

Si c'est une opération que tu fais souvent, fais toi un decorateur comme raccourcis :

def rpc(*args, **kwargs):
    def decorator(func):
        func = inlineCallback(func)
        func = wamp.register(*args, **kwargs)(func)
        return func
    return decorator

rpc.return = twisted.internet.defer.returnValue

Comme ça, tu peux juste faire :

from tools import rpc

    @rpc(TOPICS.move)
    def moveReg(self):
        res = yield self.call(TOPICS.coverArea, arg1, arg2)
        rpc.return(res)
répondu 1-Jan-2015 par Sam (5,000 points)
sélectionné 1-Jan-2015 par Vayel

Le problème, c'est que, dans mon cas, arg1 et arg2 sont des entiers (vérifié). D'ailleurs, les remplacer par des 0 ne change rien à l'erreur.

A noter que la fonction décorée par @wamp.register(TOPICS.coverArea) s'exécute correctement.

Mais putain, c'est ma valeur de retour qui fait chier !

@wamp.register(TOPICS.coverArea)
def coverAreaReg(self, rowIndex, areaIndex):
    successes = ["blabla"]
    errors = ["blabla"]    

    if self.data.coverArea(rowIndex, areaIndex):
        self.publish(TOPICS.data, pickle.dumps(self.data))
        self.publish(TOPICS.jsonData, self.data.json)

        return successes
    else:
        return errors

Le print ci-dessous m'affiche "[Deferred at 0xa0c148c]" (avec des chevrons, mais l'éditeur me fait chier avec ça) et non pas un tableau comme je le souhaiterais. D'où le problème de serialisation.

@wamp.register(TOPICS.move)
def moveReg(self):
    res = self.call(TOPICS.coverArea, arg1, arg2)

    print(res)

    return res

Par contre, j'ignore comment y remédier. J'ai essayé via la fonction returnValue de twisted.internet.defer, mais ça ne change rien.

Ok, j'ai édité la réponse.

Parfait, merci beaucoup !

...