WAMP v2 Factory

#1

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

0 Likes

#2

Hi Daniel,

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.

···

Am 08.09.2014 16:00, schrieb Daniel Faust:

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.

0 Likes