Bienvenue sur IndexError.

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

Mais aussi sur les technos front comme React, Angular, Typescript et Javascript en général.

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,050 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

+4 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 (4,978 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 !

...