Используя подход Decorator с AutobahnWS, как публиковать сообщения независимо от обратных вызовов подписки и ссылки на сеанс?

При работе с Autobahn и WAMP до того, как я использовал подход к подклассам, но наткнулся на подход декоратора/функций, который я действительно предпочитаю подклассам.

Однако. У меня есть функция, которая вызывается с внешнего оборудования (через обратный вызов), и эта функция должна публиковаться на маршрутизаторе Crossbar.io всякий раз, когда она вызывается.

Вот как я это сделал, сохранив ссылку на Session сразу после вызова on_join -> async def joined(session, details).

from autobahn.asyncio.component import Component
from autobahn.asyncio.component import run

global_session = None

comp = Component(
    transports=u"ws://localhost:8080/ws",
    realm=u"realm1",
)

def callback_from_hardware(msg):
    if global_session is None:
        return
    global_session.publish(u'com.someapp.somechannel', msg)

@comp.on_join
async def joined(session, details):
    global global_session
    global_session = session
    print("session ready")

if __name__ == "__main__":
    run([comp])

Однако такой подход сохранения ссылки после того, как компонент присоединился к соединению, кажется немного «странным». Есть ли другой подход к этому? Может это сделать по-другому.

Если нет, то это кажется немного более «правильным» с подклассами и наличием всего кода, зависящего от приложения, в этом подклассе (но, тем не менее, сохранение всего моего приложения в одном подклассе также кажется странным).


person Simon Kemper    schedule 09.01.2018    source источник


Ответы (2)


Я бы рекомендовал использовать асинхронную очередь вместо общего сеанса:

import asyncio

from autobahn.asyncio.component import Component
from autobahn.asyncio.component import run

queue = asyncio.queues.Queue()

comp = Component(
    transports=u"ws://localhost:8080/ws",
    realm=u"realm1",
)


def callback_from_hardware(msg):
    queue.put_nowait((u'com.someapp.somechannel', msg,))


@comp.on_join
async def joined(session, details):
    print("session ready")

    while True:
        topic, message, = await queue.get()
        print("Publishing: topic: `%s`, message: `%s`" % (topic, message))
        session.publish(topic, message)


if __name__ == "__main__":
    callback_from_hardware("dassdasdasd")
    run([comp])
person Andrey Belyak    schedule 27.02.2018

Есть несколько подходов, которые вы могли бы использовать здесь, хотя самым простым IMO было бы использование http-моста Crossbar. Таким образом, всякий раз, когда от вашего оборудования поступает обратный вызов события, вы можете просто отправить HTTP-запрос POST в Crossbar, и ваше сообщение будет доставлено.

Подробнее о http bridge https://crossbar.io/docs/HTTP-Bridge-Publisher/

person Omer Akram    schedule 28.03.2018
comment
Не могли бы вы обобщить соответствующие разделы из связанного ресурса? - person ; 29.03.2018