WAMP v2 Factory

49 views
Skip to first unread message

Daniel Faust

unread,
Sep 8, 2014, 10:00:17 AM9/8/14
to autob...@googlegroups.com
Hi there,

I'm currently learning WAMP v2. I've used v1 extensively, so I was a bit surprised after reading through the twisted/wamp/basic/ examples. I like a lot what I saw there.

So what I'm trying to do is to modify the basicrouter in order to get more insight, and see how flexible it is in order to add some access control in there in the future, also some logging capabilities (to log messages into a database).

The core of what I'm trying to understand is in these lines:
router_factory    = RouterFactory()
session_factory   = RouterSessionFactory(router_factory)
# (2) session_factory.session = MyRouterSession
transport_factory = WampWebSocketServerFactory(session_factory, debug = False)
# (1) transport_factory.protocol = MyWampWebSocketServerProtocol
# (3) transport_factory.shared = {'test': 'data'}

(1) I've managed to get access to the protocol instances by attaching MyWampWebSocketServerProtocol to transport_factory.protocol, where MyWampWebSocketServerProtocol is obtained by deriving from WampWebSocketServerProtocol, which is obtained through
from autobahn.twisted.websocket import WampWebSocketServerProtocol

This works fine, just like in v1, there I can intercept onOpen, onClose and onMessage, which is fine for logging.

My problem arises when I want to access the factory from a protocol instance. In v1 the protocol's instances self.factory contained the factory, which could easily be modified by subclassing from WampServerFactory in order to contain some shared state and functionality. There I used to store some shared data as well as a list of connected clients, as well as references to other classes to which protocol instances should have access to.

(2) The closest I came to reproducing the v1 factory behaviour was by assigning a MyRouterSession to session_factory.session, where MyRouterSession is derived from RouterSession which is imported via
from autobahn.twisted.wamp import RouterSession"

There I can intercept onOpen, onJoin, and others wihtout problem, but I noticed that I don't have access to this factory via the protocols self.factory variable, since that one is containing a WampWebSocketServerFactory, which has me a bit confused.

(3) So I'm able to access shared state if I place it at the transport_factory, but what differs from the behaviour to v1 is that this shared state data no longer is in the factory where I'm overriding the methods. This means that my factory customisations got spread over two classes, where I'm not sure what their relation is, and adding custom methods to the factory is no longer a clean thing if I want them to be accessible from the protocol instances. Also, I don't know how to access the MyRouterSession from the WampWebSocketServerFactory.

Is there somewhere a simple example which shows me how to do this? Remember, I'm trying to modify the baserouter in order to have all the example back- and frontends working on that one and see the data passing by.

It's a bit hard to explain, but maybe the core of the problem is that I'm not understanding why there are suddenly 3 factories while v1 only had 1 factory.

It really made me smile when I noticed that the back- and frontends communicate through that basicrouter. Interesting stuff.

Greetings,
Daniel


Tobias Oberstein

unread,
Sep 11, 2014, 3:44:34 AM9/11/14
to autob...@googlegroups.com
Hi Daniel,

Am 08.09.2014 16:00, schrieb Daniel Faust:
> Hi there,
>
> I'm currently learning WAMP v2. I've used v1 extensively, so I was a bit
> surprised after reading through the twisted/wamp/basic/ examples. I like
> a lot what I saw there.

Great!

>
> So what I'm trying to do is to modify the basicrouter in order to get
> more insight, and see how flexible it is in order to add some access
> control in there in the future, also some logging capabilities (to log
> messages into a database).

As a general note: with WAMP v2, routers are supposed to be generic and
not run any application specific code.

When using AutobahnPython, application code should be written using the
classes listed here:

https://github.com/tavendo/AutobahnPython/wiki/Programming-Guide#writing-wamp-applications

I'll add more to that Wiki page over the coming days - as it seems there
is some confusion rgd which classes are intended for what use.

>
> The core of what I'm trying to understand is in these lines:
> router_factory = RouterFactory()
> session_factory = RouterSessionFactory(router_factory)
> # (2) session_factory.session = *My*RouterSession
> transport_factory = WampWebSocketServerFactory(session_factory, debug =
> False)
> # (1) transport_factory.protocol = *My*WampWebSocketServerProtocol
> # (3) transport_factory.shared = {'test': 'data'}
>
> (1) I've managed to get access to the protocol instances by attaching
> /*My*WampWebSocketServerProtocol/ to transport_factory.protocol, where
> /*My*WampWebSocketServerProtocol/ is obtained by deriving from
> /WampWebSocketServerProtocol/, which is obtained through
> /from autobahn.twisted.websocket import WampWebSocketServerProtocol/
>
> This works fine, just like in v1, there I can intercept onOpen, onClose
> and onMessage, which is fine for logging.
>
> My problem arises when I want to access the factory from a protocol
> instance. In v1 the protocol's instances /self.factory /contained the
> factory, which could easily be modified by subclassing from
> /WampServerFactory/ in order to contain some shared state and

What shared state? There must not be any application specific state
attached to anything router related.

Of course you can technically do, but you a breaking WAMP paradigms and
AutobahnPython design doing so. This will inevitably lead to pains down
the road.

> functionality. There I used to store some shared data as well as a list
> of connected clients, as well as references to other classes to which
> protocol instances should have access to.
>
> (2) The closest I came to reproducing the v1 factory behaviour was by
> assigning a /*My*RouterSession /to session_factory.session, where
> /*My*RouterSession /is derived from /RouterSession /which is imported via
> /from autobahn.twisted.wamp import RouterSession/"
>
> There I can intercept onOpen, onJoin, and others wihtout problem, but I
> noticed that I don't have access to this factory via the protocols
> /self.factory /variable, since that one is containing a
> /WampWebSocketServerFactory/, which has me a bit confused.
>
> (3) So I'm able to access shared state if I place it at the
> transport_factory, but what differs from the behaviour to v1 is that
> this shared state data no longer is in the factory where I'm overriding

Again, don't share application state using router related classes. Also,
please note that a single router might be fed by multiple transport
factories, since WAMP v2 can run multiple transports. So sharing state
on a specific transport factory also doesn't make a lot of sense - even
technically.

> the methods. This means that my factory customisations got spread over
> two classes, where I'm not sure what their relation is, and adding
> custom methods to the factory is no longer a clean thing if I want them
> to be accessible from the protocol instances. Also, I don't know how to
> access the MyRouterSession from the WampWebSocketServerFactory.
>
> Is there somewhere a simple example which shows me how to do this?
> Remember, I'm trying to modify the baserouter in order to have all the
> example back- and frontends working on that one and see the data passing by.
>
> It's a bit hard to explain, but maybe the core of the problem is that
> I'm not understanding why there are suddenly 3 factories while v1 only
> had 1 factory.

Yes. There are 3 factories:

- router factories, that given a realm create a router
- transport factories, that create protocol instances (WebSocket,
RawSocket, ..)
- router session factories, that create the router side representation
of a WAMP session

Above is the basis for the fexibility of AutobahnPython provides with
WAMP 2: transport independence and realm based routing.

Writing custom drivers and routers is an advanced topic that most users
should not bother at all.

In no case should you write drivers/routers that run application
specific code.

I'd recommend having a look at Crossbar if you look for an advanced
router based on AutobahnPython. If you want to cook your own, these are
the classes that Crossbar itself uses:

https://github.com/tavendo/AutobahnPython/wiki/Programming-Guide#creating-custom-drivers-and-routers

There is no API guarantees for this currently. We might change it, your
code might break, etc.

>
> It really made me smile when I noticed that the back- and frontends
> communicate through that basicrouter. Interesting stuff.

Great! WAMP 2 is a major step. It fully realizes the original vision we
had with WAMP.

>
> Greetings,
> Daniel
>
>
> --
> You received this message because you are subscribed to the Google
> Groups "Autobahn" group.
> To unsubscribe from this group and stop receiving emails from it, send
> an email to autobahnws+...@googlegroups.com
> <mailto:autobahnws+...@googlegroups.com>.
> To post to this group, send email to autob...@googlegroups.com
> <mailto:autob...@googlegroups.com>.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/autobahnws/08fa6f3b-db64-42f0-90f3-3132ebc5fb99%40googlegroups.com
> <https://groups.google.com/d/msgid/autobahnws/08fa6f3b-db64-42f0-90f3-3132ebc5fb99%40googlegroups.com?utm_medium=email&utm_source=footer>.
> For more options, visit https://groups.google.com/d/optout.

Reply all
Reply to author
Forward
0 new messages