crossbar.io: reasons why onJoin() might not be called?

308 views
Skip to first unread message

Scott Wittenburg

unread,
Aug 22, 2014, 5:14:31 PM8/22/14
to autob...@googlegroups.com
Hi all,

   I'm trying to take an existing class which extends ApplicationSession and get crossbar.io to start it for me, along with starting a router for it.  I started by typing:

crossbar init --template hello:python --appdir hello

and then trying to modify what was generated to match my situation.  My modified config.json looks like this:

{
   "controller": {
   },
   "workers": [
      {
         "type": "router",
         "options": {
            "pythonpath": [".."]
         },
         "realms": [
            {
               "name": "vtkweb",
               "roles": [
                  {
                     "name": "anonymous",
                     "permissions": [
                        {
                           "uri": "*",
                           "publish": true,
                           "subscribe": true,
                           "call": true,
                           "register": true
                        }
                     ]
                  }
               ]
            }
         ],
         "transports": [
            {
               "type": "web",
               "endpoint": {
                  "type": "tcp",
                  "port": 8080
               },
               "paths": {
                  "/": {
                     "type": "static",
                     "directory": ".../www"
                  },
                  "ws": {
                     "type": "websocket"
                  }
               }
            }
         ]
      },
      {
         "type": "container",
         "options": {
            "pythonpath": [".../lib/site-packages",".../lib"]
         },
         "components": [
            {
               "type": "class",
               "classname": "paraview.web.pv_web_visualizer._VisualizerServer",
               "realm": "vtkweb",
               "transport": {
                  "type": "websocket",
                  "endpoint": {
                     "type": "tcp",
                     "host": "127.0.0.1",
                     "port": 8080
                  },
                  "url": "ws://127.0.0.1:8080/ws"
               }
            }
         ]
      }
   ]
}

And here is my modified setup.py (Is this actually needed, or might the config.json be enough?):

from setuptools import setup

setup(
    name = 'pvtest',
    version = '0.0.1',
    description = "'pvtest' WAMP Component",
    platforms = ['Any'],
    packages = ['paraview'],
    include_package_data = True,
    zip_safe = False,
    entry_points = {
        'autobahn.twisted.wamplet': [
            'backend = paraview.web.pv_web_visualizer:_VisualizerServer'
        ],
    }
)

Here is what I am pretty sure is working:

1) the static site is up and working, I can load content from the directory I have specified

2) I have run crossbar with "-d" and used logging to verify that my ApplicationSession component is getting constructed.  But the onJoin() method is never called.  If I understand correctly (a huge assumption here), onJoin() should be called when the transport is set up, which is something that happens between the router and the application component.  Is that correct?  

So, does anyone see something obvious I could be doing wrong?  Any idea why my onJoin() method is never called?  

Thanks!
Scott


Tobias Oberstein

unread,
Aug 23, 2014, 7:50:18 AM8/23/14
to autob...@googlegroups.com
Hi Scott,

> I'm trying to take an existing class which extends
> ApplicationSession and get crossbar.io <http://crossbar.io> to start it
> for me, along with starting a router for it. I started by typing:
>
> crossbar init --template hello:python --appdir hello

That's a good way to start, since you can first assure yourself that the
(unmodifed) thing actually works (know-good) and then tweak from there.
> <http://127.0.0.1:8080/ws>"
> }
> }
> ]
> }
> ]
> }

This looks good to me (not sure about the 3 dots .. why 3 and not 2?)

Is your dir structure like this?

hello/.crossbar
hello/lib
hello/lib/site-packages
hello/lib/site-packages/paraview/web/pv_web_visualizer.py

and a class

class _VisualizerServer(ApplicationSession)

in pv_web_visualizer.py?

Since this is where CB would look after the component.

Probably you could send the output of

ls -la hello

to let me check (discloses the filenames of your app .. if that is ok
for you).

Or check manually that the file is syntactically correct and can be found

cd .crossbar
PYTHONPATH=".../lib/site-packages;.../lib" python -m
paraview.web.pv_web_visualizer

>
> And here is my modified setup.py (Is this actually needed, or might the
> config.json be enough?):

If you are using a component of type "class", you don't need the
setup.py at all.

With "class", all that is needed is the "classname" and "pythonpath" in
config.

The "setup.py" is when you want to distribute your component as a proper
Python package. If you do so, then you would use type "wamplet" as
component type. CB then finds your class via the "entry_points" from the
setup.py

> ..

> Here is what I am pretty sure is working:
>
> 1) the static site is up and working, I can load content from the
> directory I have specified
>
> 2) I have run crossbar with "-d" and used logging to verify that my
> ApplicationSession component is getting constructed. But the onJoin()
> method is never called. If I understand correctly (a huge assumption
> here), onJoin() should be called when the transport is set up, which is
> something that happens between the router and the application component.
> Is that correct?

Nearly.

A component connects to a router over a WAMP transport. When the
transport is established, the onConnect() callback on your
ApplicationSession fires. The default implementation of onConnect() then
calls join() to actually attach the session to a realm.

When the session then actually has attached, the onJoin() callback
fires. Now the session is ready.

Note: between onConnect() and onJoin() there are authentication related
callbacks.


>
> So, does anyone see something obvious I could be doing wrong? Any idea
> why my onJoin() method is never called?

Could you modify your config for

"url": "ws://127.0.0.1:8080/ws",
"debug": true

and send us log output?

>
> Thanks!
> Scott
>
>
> --
> 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/CAPiw4fCNgnQh0TSUT1P_sgWYHaj0oo%3D8_gGZrSQvki5dDadAnw%40mail.gmail.com
> <https://groups.google.com/d/msgid/autobahnws/CAPiw4fCNgnQh0TSUT1P_sgWYHaj0oo%3D8_gGZrSQvki5dDadAnw%40mail.gmail.com?utm_medium=email&utm_source=footer>.
> For more options, visit https://groups.google.com/d/optout.

Scott Wittenburg

unread,
Aug 26, 2014, 5:18:33 PM8/26/14
to autob...@googlegroups.com
Hi Tobias,

   Sorry to take so long to respond, I usually see an email in my inbox, but this time I didn't.  I'm glad I finally came back to the forum to check!  Anyway, thanks for responding so quickly :-) 

   My replies are inlined, I really appreciate your help, thanks!


On Saturday, August 23, 2014 5:50:18 AM UTC-6, Tobias Oberstein wrote:
Hi Scott,

 >     I'm trying to take an existing class which extends
> ApplicationSession and get crossbar.io <http://crossbar.io> to start it
> for me, along with starting a router for it.  I started by typing:
>
> crossbar init --template hello:python --appdir hello

That's a good way to start, since you can first assure yourself that the
(unmodifed) thing actually works (know-good) and then tweak from there.  
 
Yep, the basic one worked just great.  Specifically, no problem with rpc call registered on the server and called from the Javascript client.
Sorry for introducing that confusion, the three dots were meant to indicate "stuff left out".  The path is actually an absolute one, and I think it's fine because I figured out how to log from my application component, and I can see I'm getting inside a couple methods of my class.  As you'll see in my log output.   
>
> And here is my modified setup.py (Is this actually needed, or might the
> config.json be enough?):

If you are using a component of type "class", you don't need the
setup.py at all.

With "class", all that is needed is the "classname" and "pythonpath" in
config.

The "setup.py" is when you want to distribute your component as a proper
Python package. If you do so, then you would use type "wamplet" as
component type. CB then finds your class via the "entry_points" from the
setup.py

This is great, just what we were hoping for ! 
>  ..

> Here is what I am pretty sure is working:
>
> 1) the static site is up and working, I can load content from the
> directory I have specified
>
> 2) I have run crossbar with "-d" and used logging to verify that my
> ApplicationSession component is getting constructed.  But the onJoin()
> method is never called.  If I understand correctly (a huge assumption
> here), onJoin() should be called when the transport is set up, which is
> something that happens between the router and the application component.
>   Is that correct?

Nearly.

A component connects to a router over a WAMP transport. When the
transport is established, the onConnect() callback on your
ApplicationSession fires. The default implementation of onConnect() then
calls join() to actually attach the session to a realm.

When the session then actually has attached, the onJoin() callback
fires. Now the session is ready.

Note: between onConnect() and onJoin() there are authentication related
callbacks.


Hmmm, I see, thanks for the explanation.  FWIW, my class that extends ApplicationSession logs messages inside the onJoin and onConnect, and neither get called.
>
> So, does anyone see something obvious I could be doing wrong?  Any idea
> why my onJoin() method is never called?

Could you modify your config for

                   "url": "ws://127.0.0.1:8080/ws",
                   "debug": true

and send us log output?

So I have modified the config to do the logging you requested, and here is the result: (Note that log entries beginning with "*****   " are coming from my class that extends ApplicationSession, so I know the Python path is correct and my class is getting constructed)

scott@solaris:~/Documents/crossbar-tests/pvtest$ crossbar -d start
2014-08-26 15:10:50-0600 [Controller  10367] Log opened.
2014-08-26 15:10:50-0600 [Controller  10367] ============================== Crossbar.io ==============================
2014-08-26 15:10:50-0600 [Controller  10367] Crossbar.io 0.9.7-5 starting
2014-08-26 15:10:50-0600 [Controller  10367] Automatically choosing optimal Twisted reactor
2014-08-26 15:10:52-0600 [Controller  10367] Running Twisted reactor twisted.internet.epollreactor.EPollReactor
2014-08-26 15:10:52-0600 [Controller  10367] Running on CPython using EPollReactor reactor
2014-08-26 15:10:52-0600 [Controller  10367] Starting from node directory /home/scott/Documents/crossbar-tests/pvtest/.crossbar
2014-08-26 15:10:52-0600 [Controller  10367] Starting from local configuration '/home/scott/Documents/crossbar-tests/pvtest/.crossbar/config.json'
2014-08-26 15:10:52-0600 [Controller  10367] No WAMPlets detected in enviroment.
2014-08-26 15:10:52-0600 [Controller  10367] Starting Router with ID 'worker1' ..
2014-08-26 15:10:53-0600 [Router      10376] Log opened.
2014-08-26 15:10:54-0600 [Router      10376] Running under CPython using EPollReactor reactor
2014-08-26 15:10:55-0600 [Router      10376] Entering event loop ..
2014-08-26 15:10:55-0600 [Controller  10367] Router with ID 'worker1' and PID 10376 started
2014-08-26 15:10:55-0600 [Controller  10367] Router 'worker1': PYTHONPATH extended
2014-08-26 15:10:55-0600 [Controller  10367] Router 'worker1': realm 'realm1' started
2014-08-26 15:10:55-0600 [Controller  10367] Router 'worker1': role 'role1' started on realm 'realm1'
2014-08-26 15:10:55-0600 [Router      10376] Site starting on 8080
2014-08-26 15:10:55-0600 [Controller  10367] Router 'worker1': transport 'transport1' started
2014-08-26 15:10:55-0600 [Controller  10367] Starting Container with ID 'worker2' ..
2014-08-26 15:10:55-0600 [Container   10381] Log opened.
2014-08-26 15:10:57-0600 [Container   10381] Running under CPython using EPollReactor reactor
2014-08-26 15:10:57-0600 [Container   10381] Entering event loop ..
2014-08-26 15:10:57-0600 [Controller  10367] Container with ID 'worker2' and PID 10381 started
2014-08-26 15:10:57-0600 [Controller  10367] Container 'worker2': PYTHONPATH extended
2014-08-26 15:11:05-0600 [Container   10381] [('debug', True, 'CrossbarWampWebSocketClientFactory'),
2014-08-26 15:11:05-0600 [Container   10381] ('debugCodePaths', False, 'CrossbarWampWebSocketClientFactory'),
2014-08-26 15:11:05-0600 [Container   10381] ('logOctets', True, 'CrossbarWampWebSocketClientFactory'),
2014-08-26 15:11:05-0600 [Container   10381] ('logFrames', True, 'CrossbarWampWebSocketClientFactory'),
2014-08-26 15:11:05-0600 [Container   10381] ('trackTimings', False, 'CrossbarWampWebSocketClientFactory'),
2014-08-26 15:11:05-0600 [Container   10381] ('allowHixie76', False, 'CrossbarWampWebSocketClientFactory'),
2014-08-26 15:11:05-0600 [Container   10381] ('utf8validateIncoming', True, 'CrossbarWampWebSocketClientFactory'),
2014-08-26 15:11:05-0600 [Container   10381] ('applyMask', True, 'CrossbarWampWebSocketClientFactory'),
2014-08-26 15:11:05-0600 [Container   10381] ('maxFramePayloadSize', 0, 'CrossbarWampWebSocketClientFactory'),
2014-08-26 15:11:05-0600 [Container   10381] ('maxMessagePayloadSize', 0, 'CrossbarWampWebSocketClientFactory'),
2014-08-26 15:11:05-0600 [Container   10381] ('autoFragmentSize', 0, 'CrossbarWampWebSocketClientFactory'),
2014-08-26 15:11:05-0600 [Container   10381] ('failByDrop', True, 'CrossbarWampWebSocketClientFactory'),
2014-08-26 15:11:05-0600 [Container   10381] ('echoCloseCodeReason', False, 'CrossbarWampWebSocketClientFactory'),
2014-08-26 15:11:05-0600 [Container   10381] ('openHandshakeTimeout', 5, 'CrossbarWampWebSocketClientFactory'),
2014-08-26 15:11:05-0600 [Container   10381] ('closeHandshakeTimeout', 1, 'CrossbarWampWebSocketClientFactory'),
2014-08-26 15:11:05-0600 [Container   10381] ('tcpNoDelay', True, 'CrossbarWampWebSocketClientFactory'),
2014-08-26 15:11:05-0600 [Container   10381] ('autoPingInterval', 0, 'CrossbarWampWebSocketClientFactory'),
2014-08-26 15:11:05-0600 [Container   10381] ('autoPingTimeout', 0, 'CrossbarWampWebSocketClientFactory'),
2014-08-26 15:11:05-0600 [Container   10381] ('autoPingSize', 4, 'CrossbarWampWebSocketClientFactory'),
2014-08-26 15:11:05-0600 [Container   10381] ('version', 18, 'CrossbarWampWebSocketClientFactory'),
2014-08-26 15:11:05-0600 [Container   10381] ('acceptMaskedServerFrames', False, 'CrossbarWampWebSocketClientFactory'),
2014-08-26 15:11:05-0600 [Container   10381] ('maskClientFrames', True, 'CrossbarWampWebSocketClientFactory'),
2014-08-26 15:11:05-0600 [Container   10381] ('serverConnectionDropTimeout', 1, 'CrossbarWampWebSocketClientFactory'),
2014-08-26 15:11:05-0600 [Container   10381] ('perMessageCompressionOffers', [], 'CrossbarWampWebSocketClientFactory'),
2014-08-26 15:11:05-0600 [Container   10381] ('perMessageCompressionAccept',
2014-08-26 15:11:05-0600 [Container   10381] <function <lambda> at 0x7fe70fe90f50>,
2014-08-26 15:11:05-0600 [Container   10381] 'CrossbarWampWebSocketClientFactory')]
2014-08-26 15:11:05-0600 [Container   10381] connection to 127.0.0.1:8080 established
2014-08-26 15:11:05-0600 [Container   10381] TX Octets to 127.0.0.1:8080 : sync = False, octets = 474554202f777320485454502f312e310d0a557365722d4167656e743a204175746f6261686e507974686f6e2f302e382e31340d0a486f73743a203132372e302e302e313a383038300d0a557067726164653a20576562536f636b65740d0a436f6e6e656374696f6e3a20557067726164650d0a507261676d613a206e6f2d63616368650d0a43616368652d436f6e74726f6c3a206e6f2d63616368650d0a5365632d576562536f636b65742d4b65793a206a715439307544457956776b534a6b5362644b4268773d3d0d0a5365632d576562536f636b65742d50726f746f636f6c3a2077616d702e322e6d73677061636b2e626174636865642c77616d702e322e6d73677061636b2c77616d702e322e6a736f6e2e626174636865642c77616d702e322e6a736f6e0d0a5365632d576562536f636b65742d56657273696f6e3a2031330d0a0d0a
2014-08-26 15:11:05-0600 [Container   10381] GET /ws HTTP/1.1
2014-08-26 15:11:05-0600 [Container   10381] User-Agent: AutobahnPython/0.8.14
2014-08-26 15:11:05-0600 [Container   10381] Host: 127.0.0.1:8080
2014-08-26 15:11:05-0600 [Container   10381] Upgrade: WebSocket
2014-08-26 15:11:05-0600 [Container   10381] Connection: Upgrade
2014-08-26 15:11:05-0600 [Container   10381] Pragma: no-cache
2014-08-26 15:11:05-0600 [Container   10381] Cache-Control: no-cache
2014-08-26 15:11:05-0600 [Container   10381] Sec-WebSocket-Key: jqT90uDEyVwkSJkSbdKBhw==
2014-08-26 15:11:05-0600 [Container   10381] Sec-WebSocket-Protocol: wamp.2.msgpack.batched,wamp.2.msgpack,wamp.2.json.batched,wamp.2.json
2014-08-26 15:11:05-0600 [Container   10381] Sec-WebSocket-Version: 13
2014-08-26 15:11:05-0600 [Container   10381] RX Octets from 127.0.0.1:8080 : octets = 485454502f312e312031303120537769746368696e672050726f746f636f6c730d0a5365727665723a2043726f73736261722f302e392e372d350d0a557067726164653a20576562536f636b65740d0a436f6e6e656374696f6e3a20557067726164650d0a5365632d576562536f636b65742d50726f746f636f6c3a2077616d702e322e6d73677061636b2e626174636865640d0a5365632d576562536f636b65742d4163636570743a206959774472486d69684b554d5062683166584c6a4c754c61564d413d0d0a0d0a
2014-08-26 15:11:05-0600 [Container   10381] received HTTP response:
2014-08-26 15:11:05-0600 [Container   10381] HTTP/1.1 101 Switching Protocols
2014-08-26 15:11:05-0600 [Container   10381] Server: Crossbar/0.9.7-5
2014-08-26 15:11:05-0600 [Container   10381] Upgrade: WebSocket
2014-08-26 15:11:05-0600 [Container   10381] Connection: Upgrade
2014-08-26 15:11:05-0600 [Container   10381] Sec-WebSocket-Protocol: wamp.2.msgpack.batched
2014-08-26 15:11:05-0600 [Container   10381] Sec-WebSocket-Accept: iYwDrHmihKUMPbh1fXLjLuLaVMA=
2014-08-26 15:11:05-0600 [Container   10381] received HTTP status line in opening handshake : HTTP/1.1 101 Switching Protocols
2014-08-26 15:11:05-0600 [Container   10381] received HTTP headers in opening handshake : {u'connection': u'Upgrade', u'upgrade': u'WebSocket', u'sec-websocket-protocol': u'wamp.2.msgpack.batched', u'sec-websocket-accept': u'iYwDrHmihKUMPbh1fXLjLuLaVMA=', u'server': u'Crossbar/0.9.7-5'}
2014-08-26 15:11:05-0600 [Container   10381] *****   Inside ServerProtocol constructor
2014-08-26 15:11:05-0600 [Container   10381] *****   Adding protocol to be registered later: <class 'paraview.web.protocols.ParaViewWebStartupRemoteConnection'>
2014-08-26 15:11:05-0600 [Container   10381] *****   Adding protocol to be registered later: <class 'paraview.web.protocols.ParaViewWebStartupPluginLoader'>
2014-08-26 15:11:05-0600 [Container   10381] *****   Adding protocol to be registered later: <class 'paraview.web.protocols.ParaViewWebStateLoader'>
2014-08-26 15:11:05-0600 [Container   10381] *****   Adding protocol to be registered later: <class 'paraview.web.protocols.ParaViewWebFileListing'>
2014-08-26 15:11:05-0600 [Controller  10367] Container 'worker2': component 'component1' started
2014-08-26 15:11:05-0600 [Container   10381] *****   Adding protocol to be registered later: <class 'paraview.web.protocols.ParaViewWebProxyManager'>
2014-08-26 15:11:05-0600 [Container   10381] *****   Adding protocol to be registered later: <class 'paraview.web.protocols.ParaViewWebColorManager'>
2014-08-26 15:11:05-0600 [Container   10381] *****   Adding protocol to be registered later: <class 'paraview.web.protocols.ParaViewWebMouseHandler'>
2014-08-26 15:11:05-0600 [Container   10381] *****   Adding protocol to be registered later: <class 'paraview.web.protocols.ParaViewWebViewPort'>
2014-08-26 15:11:05-0600 [Container   10381] *****   Adding protocol to be registered later: <class 'paraview.web.protocols.ParaViewWebViewPortImageDelivery'>
2014-08-26 15:11:05-0600 [Container   10381] *****   Adding protocol to be registered later: <class 'paraview.web.protocols.ParaViewWebViewPortGeometryDelivery'>
2014-08-26 15:11:05-0600 [Container   10381] *****   Adding protocol to be registered later: <class 'paraview.web.protocols.ParaViewWebTimeHandler'>
2014-08-26 15:11:05-0600 [Container   10381] *****   Adding protocol to be registered later: <class 'paraview.web.protocols.ParaViewWebSelectionHandler'>
2014-08-26 15:11:05-0600 [Container   10381] *****   Adding protocol to be registered later: <class 'paraview.web.protocols.ParaViewWebWidgetManager'>
2014-08-26 15:11:05-0600 [Container   10381] connection to 127.0.0.1:8080 lost

For completeness, here is the html I'm using to connect from the client side, though I don't think I'm quite getting that far yet :-)  Though it connects, it is unable to call the rpc method, which makes sense, because those methods are registered in my onJoin() method, which isn't getting called.

<!DOCTYPE html>
<html>
   <body>
      <h1>Hello WAMP</h1>
      <p>Open JavaScript console to watch output.</p>
      <script>AUTOBAHN_DEBUG = true;</script>
      <script src="ext/core/autobahn.min.js"></script>

      <script>
         // the WAMP connection to the Router
         //
         var connection = new autobahn.Connection({
            url: "ws://127.0.0.1:8080/ws",
            realm: "vtkweb"
         });

         // fired when connection is established and session attached
         //
         connection.onopen = function (session, details) {
            console.log("Connected");

            session.call('file.server.directory.list').then(
                function(res) {
                    console.log("Successfully called rpc method:");
                    console.log(obj);
                },
                function(err) {
                    console.log("Error calling pv.files.list:");
                    console.log(err);
                });
         };

         // fired when connection was lost (or could not be established)
         //
         connection.onclose = function (reason, details) {
            console.log("Connection lost: " + reason);
         }

         // now actually open the connection
         //
         connection.open();

      </script>
   </body>
</html>

The console output from this html is:

AutobahnJS debug enabled autobahn.min.js:20
Connected (index):20
Error calling pv.files.list: (index):28
d {error"wamp.error.no_such_procedure"argsArray[1]kwargsObject}
  1. argsArray[1]
    1. 0"no procedure 'file.server.directory.list' registered"
    2. length1
    3. __proto__Array[0]
  2. error"wamp.error.no_such_procedure"
  3. kwargsObject
  4. __proto__Object
 
Additionally, here is my complete, unaltered config file (I don't mind if any of my paths or file names are visible):

{
                     "directory": "/home/scott/projects/ParaView/build-make-debug/www"
                  },
                  "ws": {
                     "type": "websocket"
                  }
               }
            }
         ]
      },
      {
         "type": "container",
         "options": {
            "pythonpath": ["/home/scott/projects/ParaView/build-make-debug/lib/site-packages","/home/scott/projects/ParaView/build-make-debug/lib"]
         },
         "components": [
            {
               "type": "class",
               "classname": "paraview.web.pv_web_visualizer._VisualizerServer",
               "realm": "vtkweb",
               "transport": {
                  "type": "websocket",
                  "endpoint": {
                     "type": "tcp",
                     "host": "127.0.0.1",
                     "port": 8080
                  },
                  "url": "ws://127.0.0.1:8080/ws",
                  "debug": true
               }
            }
         ]
      }
   ]
}

Thanks again!

Scott

>
> Thanks!
> Scott
>
>
> --
> 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

Tobias Oberstein

unread,
Aug 27, 2014, 10:25:23 AM8/27/14
to autob...@googlegroups.com
Hi Scott,

Am 26.08.2014 23:18, schrieb Scott Wittenburg:
> Hi Tobias,
>
> Sorry to take so long to respond, I usually see an email in my
> inbox, but this time I didn't. I'm glad I finally came back to the
> forum to check! Anyway, thanks for responding so quickly :-)

Don't worry: I still need to respond to your other mail also (rgd. auth
etc). I _will_. Was just overwhelmed again with stuff.

I hope you have patience with Crossbar.io and getting your existing app
hosted/running there. As you likely already recognized, this is still
bleeding edge stuff. Needs to stabilize a litte. Don't go to production
today;)

> A component connects to a router over a WAMP transport. When the
> transport is established, the onConnect() callback on your
> ApplicationSession fires. The default implementation of onConnect()
> then
> calls join() to actually attach the session to a realm.
>
> When the session then actually has attached, the onJoin() callback
> fires. Now the session is ready.
>
> Note: between onConnect() and onJoin() there are authentication related
> callbacks.
>
>
> Hmmm, I see, thanks for the explanation. FWIW, my class that extends
> ApplicationSession logs messages inside the onJoin and onConnect, and
> neither get called.

This likely means the establishment of WAMP transport itself already fails.

> So I have modified the config to do the logging you requested, and here
> is the result: (Note that log entries beginning with "***** " are
> coming from my class that extends ApplicationSession, so I know the
> Python path is correct and my class is getting constructed)

Good: one source of error eliminated.

> 2014-08-26 15:11:05-0600 [Container 10381] connection to
> 127.0.0.1:8080 lost

This is bad.

The WebSocket connection is established, but before the WAMP session has
attached to the Router realm, it fails.

> For completeness, here is the html I'm using to connect from the client
> side, though I don't think I'm quite getting that far yet :-) Though it
> connects, it is unable to call the rpc method, which makes sense,
> because those methods are registered in my onJoin() method, which isn't
> getting called.

Yes. That's a consequence of the Callee component above not actually
being attached to the Router realm.

Could you please try the attached config with your CB?

This is running the app component "side-by-side" inside the Router
worker. This does away with any actual transport .. might help finding
out what's going on. If it doesn't work, please attach log output

Cheers,
/Tobias




config.json

Scott Wittenburg

unread,
Aug 27, 2014, 1:04:38 PM8/27/14
to autob...@googlegroups.com
Hi Tobias,

   Thanks for providing such great support!  I feel you're going above and beyond here, giving us specific configuration tips, checking our log files and such.  I really appreciate it!  Responses inline below...

On Wednesday, August 27, 2014 8:25:23 AM UTC-6, Tobias Oberstein wrote:
Hi Scott,

Am 26.08.2014 23:18, schrieb Scott Wittenburg:
> Hi Tobias,
>
>     Sorry to take so long to respond, I usually see an email in my
> inbox, but this time I didn't.  I'm glad I finally came back to the
> forum to check!  Anyway, thanks for responding so quickly :-)

Don't worry: I still need to respond to your other mail also (rgd. auth
etc). I _will_. Was just overwhelmed again with stuff.

No worries, I completely understand.  And anyway, I feel you've been very responsive in spite of how busy you must be.
 
I hope you have patience with Crossbar.io and getting your existing app
hosted/running there. As you likely already recognized, this is still
bleeding edge stuff. Needs to stabilize a litte. Don't go to production
today;)

Nope, we're not going to production right away :-)  I'm enjoying learning about new technology, and just kind of pursuing this tangentially for now.  But it definitely has a lot of capabilities that seem very promising for us.
 
>     A component connects to a router over a WAMP transport. When the
>     transport is established, the onConnect() callback on your
>     ApplicationSession fires. The default implementation of onConnect()
>     then
>     calls join() to actually attach the session to a realm.
>
>     When the session then actually has attached, the onJoin() callback
>     fires. Now the session is ready.
>
>     Note: between onConnect() and onJoin() there are authentication related
>     callbacks.
>
>
> Hmmm, I see, thanks for the explanation.  FWIW, my class that extends
> ApplicationSession logs messages inside the onJoin and onConnect, and
> neither get called.

This likely means the establishment of WAMP transport itself already fails.

Interesting.  This may have nothing to do with it, but I was wondering if there could be a problem with the fact that our ApplicationSession object is using one version of Autobahn python, while crossbar.io is starting the router and probably using a different version.  Could there be an issue here? 
 
> So I have modified the config to do the logging you requested, and here
> is the result: (Note that log entries beginning with "*****   " are
> coming from my class that extends ApplicationSession, so I know the
> Python path is correct and my class is getting constructed)

Good: one source of error eliminated.

> 2014-08-26 15:11:05-0600 [Container   10381] connection to
> 127.0.0.1:8080 lost

This is bad.

The WebSocket connection is established, but before the WAMP session has
attached to the Router realm, it fails.

I need to go back to the docs and read about how the realms fit into the architecture.
 
> For completeness, here is the html I'm using to connect from the client
> side, though I don't think I'm quite getting that far yet :-)  Though it
> connects, it is unable to call the rpc method, which makes sense,
> because those methods are registered in my onJoin() method, which isn't
> getting called.

Yes. That's a consequence of the Callee component above not actually
being attached to the Router realm.

Could you please try the attached config with your CB?

This is running the app component "side-by-side" inside the Router
worker. This does away with any actual transport .. might help finding
out what's going on. If it doesn't work, please attach log output

Ok, so I ran it again with the new "side-by-side" configuration.  For one thing, it's just cool to see how many different scenarios will be supported, and to see via example how many different ways there are of getting things to talk to each other.  But here's the log output after running the application inside the router:

scott@solaris:~/Documents/crossbar-tests/pvtest$ crossbar -d start
2014-08-27 10:43:05-0600 [Controller  26907] Log opened.
2014-08-27 10:43:05-0600 [Controller  26907] ============================== Crossbar.io ==============================
2014-08-27 10:43:05-0600 [Controller  26907] Crossbar.io 0.9.7-5 starting
2014-08-27 10:43:05-0600 [Controller  26907] Automatically choosing optimal Twisted reactor
2014-08-27 10:43:06-0600 [Controller  26907] Running Twisted reactor twisted.internet.epollreactor.EPollReactor
2014-08-27 10:43:06-0600 [Controller  26907] Running on CPython using EPollReactor reactor
2014-08-27 10:43:06-0600 [Controller  26907] Starting from node directory /home/scott/Documents/crossbar-tests/pvtest/.crossbar
2014-08-27 10:43:07-0600 [Controller  26907] Starting from local configuration '/home/scott/Documents/crossbar-tests/pvtest/.crossbar/config.json'
2014-08-27 10:43:07-0600 [Controller  26907] No WAMPlets detected in enviroment.
2014-08-27 10:43:07-0600 [Controller  26907] Starting Router with ID 'worker1' ..
2014-08-27 10:43:07-0600 [Router      26918] Log opened.
2014-08-27 10:43:09-0600 [Router      26918] Running under CPython using EPollReactor reactor
2014-08-27 10:43:09-0600 [Router      26918] Entering event loop ..
2014-08-27 10:43:09-0600 [Controller  26907] Router with ID 'worker1' and PID 26918 started
2014-08-27 10:43:09-0600 [Controller  26907] Router 'worker1': PYTHONPATH extended
2014-08-27 10:43:09-0600 [Controller  26907] Router 'worker1': realm 'realm1' started
2014-08-27 10:43:09-0600 [Controller  26907] Router 'worker1': role 'role1' started on realm 'realm1'
2014-08-27 10:43:17-0600 [Router      26918] *****   Inside ServerProtocol constructor
2014-08-27 10:43:17-0600 [Router      26918] *****   Adding protocol to be registered later: <class 'paraview.web.protocols.ParaViewWebStartupRemoteConnection'>
2014-08-27 10:43:17-0600 [Router      26918] *****   Adding protocol to be registered later: <class 'paraview.web.protocols.ParaViewWebStartupPluginLoader'>
2014-08-27 10:43:17-0600 [Router      26918] *****   Adding protocol to be registered later: <class 'paraview.web.protocols.ParaViewWebStateLoader'>
2014-08-27 10:43:17-0600 [Router      26918] *****   Adding protocol to be registered later: <class 'paraview.web.protocols.ParaViewWebFileListing'>
2014-08-27 10:43:17-0600 [Router      26918] *****   Adding protocol to be registered later: <class 'paraview.web.protocols.ParaViewWebProxyManager'>
2014-08-27 10:43:17-0600 [Router      26918] *****   Adding protocol to be registered later: <class 'paraview.web.protocols.ParaViewWebColorManager'>
2014-08-27 10:43:17-0600 [Router      26918] *****   Adding protocol to be registered later: <class 'paraview.web.protocols.ParaViewWebMouseHandler'>
2014-08-27 10:43:17-0600 [Router      26918] *****   Adding protocol to be registered later: <class 'paraview.web.protocols.ParaViewWebViewPort'>
2014-08-27 10:43:17-0600 [Router      26918] *****   Adding protocol to be registered later: <class 'paraview.web.protocols.ParaViewWebViewPortImageDelivery'>
2014-08-27 10:43:17-0600 [Router      26918] *****   Adding protocol to be registered later: <class 'paraview.web.protocols.ParaViewWebViewPortGeometryDelivery'>
2014-08-27 10:43:17-0600 [Router      26918] *****   Adding protocol to be registered later: <class 'paraview.web.protocols.ParaViewWebTimeHandler'>
2014-08-27 10:43:17-0600 [Router      26918] *****   Adding protocol to be registered later: <class 'paraview.web.protocols.ParaViewWebSelectionHandler'>
2014-08-27 10:43:17-0600 [Router      26918] *****   Adding protocol to be registered later: <class 'paraview.web.protocols.ParaViewWebWidgetManager'>
2014-08-27 10:43:17-0600 [Controller  26907] Traceback (most recent call last):
2014-08-27 10:43:17-0600 [Controller  26907]   File "/usr/local/lib/python2.7/dist-packages/crossbar/controller/node.py", line 187, in run_node_config
2014-08-27 10:43:17-0600 [Controller  26907]     yield self._run_node_config(config)
2014-08-27 10:43:17-0600 [Controller  26907] ApplicationError: ApplicationError('crossbar.error.class_import_failed', args = ("ComponentConfig instance has no attribute 'updateKey'",), kwargs = {})
2014-08-27 10:43:17-0600 [Controller  26907] Main loop terminated.
scott@solaris:~/Documents/crossbar-tests/pvtest$

I hope this can give you some insight to what I might be doing wrong.  Thanks again for all your help Tobias, you guys are doing a great job!

Cheers,
Scott


Cheers,
/Tobias




Tobias Oberstein

unread,
Aug 27, 2014, 2:19:37 PM8/27/14
to autob...@googlegroups.com
> Interesting. This may have nothing to do with it, but I was wondering if there could
> be a problem with the fact that our ApplicationSession object is
using one version of
> Autobahn python, while crossbar.io is starting the router and
probably using a different
> version. Could there be an issue here?

Oh. Yes. At least now since we try running the compontent side-by-side.

If you can, could you try/assure that only 1 Python version and 1
AutobahnPython is used by both?

> 2014-08-27 10:43:17-0600 [Controller 26907] ApplicationError:
> ApplicationError('crossbar.error.class_import_failed', args =
> ("ComponentConfig instance has no attribute 'updateKey'",), kwargs = {})

This is absolutely strange. There is no string "updateKey" in the whole
AutobahnPython and Crossbar source code!

The class ComponentConfig is trivial:

https://github.com/tavendo/AutobahnPython/blob/master/autobahn/autobahn/wamp/types.py#L44

I tried to Google around .. came about this

https://www.google.com/search?q=kitware+%22updateKey%22&ie=utf-8&oe=utf-8&aq=t&rls=org.mozilla:de:official&client=firefox-a&channel=sb

??

Unfortunately, the file does not exist anymore .. I only see part of the
Google cache:

vtkWebProtocols. def updateSecret(self, newSecret): if self.authdb:
self.authdb.updateKey('vtkweb', newSecret).
@exportRpc("application.exit"). def exit(self):.

Don't know if that is related ..

Can you post part of your ApplicationSession derived class? I mean in
particular the constructor and relevant code lines where you call the
base constructor?

This is strange ..

/Tobias


Scott Wittenburg

unread,
Aug 27, 2014, 3:42:05 PM8/27/14
to autob...@googlegroups.com


On Wednesday, August 27, 2014 12:19:37 PM UTC-6, Tobias Oberstein wrote:
> Interesting.  This may have nothing to do with it, but I was wondering if there could
 > be a problem with the fact that our ApplicationSession object is
using one version of
 > Autobahn python, while crossbar.io is starting the router and
probably using a different
 > version.  Could there be an issue here?

Oh. Yes. At least now since we try running the compontent side-by-side.

If you can, could you try/assure that only 1 Python version and 1
AutobahnPython is used by both?

Yes, it seems that when I pip installed crossbar.io, my system python now has access to all the autobahn and twisted classes we put into our site-packages folder.  So by renaming those site-packages directories, I believe I have forced my ApplicationSession class to use the same version of autobahn/twisted used by crossbar.  And I get the same error, which could make sense, because we are currently supplying very recent versions of autobahn/twisted with paraview/vtk.  
 
> 2014-08-27 10:43:17-0600 [Controller  26907] ApplicationError:
> ApplicationError('crossbar.error.class_import_failed', args =
> ("ComponentConfig instance has no attribute 'updateKey'",), kwargs = {})

This is absolutely strange. There is no string "updateKey" in the whole
AutobahnPython and Crossbar source code!

The class ComponentConfig is trivial:

https://github.com/tavendo/AutobahnPython/blob/master/autobahn/autobahn/wamp/types.py#L44

I tried to Google around .. came about this

https://www.google.com/search?q=kitware+%22updateKey%22&ie=utf-8&oe=utf-8&aq=t&rls=org.mozilla:de:official&client=firefox-a&channel=sb

??

Unfortunately, the file does not exist anymore .. I only see part of the
Google cache:

vtkWebProtocols. def updateSecret(self, newSecret): if self.authdb:
self.authdb.updateKey('vtkweb', newSecret).
@exportRpc("application.exit"). def exit(self):.

Don't know if that is related ..

Can you post part of your ApplicationSession derived class? I mean in
particular the constructor and relevant code lines where you call the
base constructor?

This is strange ..

Ok, yes, this is strange.  We do have such a string in our source code, as you will see below.  This is probably the time to explain some fancy stuff we're doing with our use of Autobahn.  I'm going to try to paste in here three stripped down snippets which hopefully allow you to see how things work, but you can always see exactly what we're doing by looking at our git repo, here:


But stuff is kind of spread around in there, so don't feel you have to spend time browsing around.  I'm just putting it out there in case...

So the basic idea is we try to allow people to come up with their own ApplicationSessions which can compose any of the "protocols" we have already defined (not to be confused with the Autobahn protocol package).  These "protocols" are classes which can export any number of rpc methods each, and by mixing and matching them, people should be able to come up with their own custom server application which exports exactly the rpc methods they need.

Our class that extends ApplicationSession, "ServerProtocol", can be extended by anyone who wants to write their own server application:

class ServerProtocol(ApplicationSession):
    """
    Defines the core server protocol for vtkWeb. Adds support to
    marshall/unmarshall RPC callbacks that involve ServerManager proxies as
    arguments or return values.

    Applications typically don't use this class directly, since it doesn't
    register any RPC callbacks that are required for basic web-applications with
    interactive visualizations. For that, use vtkWebServerProtocol.
    """

    def __init__(self, authdb=None):
        log.msg("   *****   Inside ServerProtocol constructor", logLevel=logging.DEBUG)
        ApplicationSession.__init__(self, types.ComponentConfig(realm = "vtkweb"))
        self.vtkWebProtocols = []
        self.authdb = authdb
        self.Application = self.initApplication()
        self.initialize()

    def initialize(self):
        """
        Let the sub class define what they need to do to properly initialize
        themselves.
        """
        pass

    def initApplication(self):
        """
        Let subclass optionally initialize a custom application in lieu
        of the default vtkWebApplication.
        """
        global application
        if not application:
            application = vtkWebApplication()
        return application

    def onConnect(self):
        log.msg("   *****   Inside onConnect method", logLevel=logging.DEBUG)
        ApplicationSession.onConnect(self)

    def onJoin(self, details):
        log.msg("   *****   Inside onJoin method", logLevel=logging.DEBUG)
        ApplicationSession.onJoin(self, details)
        self.register(self)
        for protocol in self.vtkWebProtocols:
            m = "   *****   Registering protocol: %s" % (str(protocol.__class__))
            log.msg(m, logLevel=logging.DEBUG)
            self.register(protocol)

    def setApplication(self, application):
        self.Application = application

    def registerVtkWebProtocol(self, protocol):
        m = "   *****   Adding protocol to be registered later: %s" % (str(protocol.__class__))
        log.msg(m, logLevel=logging.DEBUG)
        protocol.setApplication(self.Application)
        self.vtkWebProtocols.append(protocol)

    def getVtkWebProtocols(self):
        return self.vtkWebProtocols

    def updateSecret(self, newSecret):
        if self.authdb:
            self.authdb.updateKey('vtkweb', newSecret)

    @exportRpc("application.exit")
    def exit(self):
        """RPC callback to exit"""
        reactor.stop()

A "Protocol" class that can export any number of rpc methods, we have a lot of these classes (btw, we have imported "register" as "exportRpc" in this module for our own convenience):

class ParaViewWebFileManager():

    def __init__(self, defaultDirectoryToList):
        self.directory = defaultDirectoryToList

    @exportRpc("pv.files.list")
    def listFiles(self):
        return helper.listFiles(self.directory)

A class that extends that extends ServerProtocol and can now selectively compose any combination of rpc methods by instantiating some "Protocol" classes:

class BasicServer(ServerProtocol):

    directoryToList = '/path/to/directory'
    authKey = "vtkweb-secret"
   
    def initialize(self):
        # Bring in the components this class needs
        self.registerVtkWebProtocol(ParaViewWebFileManager(BasicServer.directoryToList))

        # Update authentication key to use
        self.updateSecret(BasicServer.authKey)

This BasicServer is doing exactly the same thing as _VisualizerServer from my previous posts, I just stripped out most of it to try and avoid a lot of unnecessary confusion.

So maybe these snippets let you see how we may have broken your expected model of registering rpc methods.  And you can see how the string updateKey is a function I intended to be calling on our AuthDb, something I explained in another thread, and which I had thought could be ignored in this case, since it should not be used at all.  Though it is present in the ServerProtocol constructor with a default value of None, and that is where the ComponentConfig constructor is invoked.  

In my snippets I have stripped out a lot of stuff (including all the import statements), in an attempt to just get across the key points.  Please let me know if I was overzealous there.

Thanks again, sorry to be so noisy on the list :-) 
 
/Tobias


Tobias Oberstein

unread,
Aug 27, 2014, 4:02:53 PM8/27/14
to autob...@googlegroups.com
Hi Scott,

> Ok, yes, this is strange. We do have such a string in our source code,
> as you will see below. This is probably the time to explain some fancy
> stuff we're doing with our use of Autobahn. I'm going to try to paste

From what I see below, yes, that is likely a source of problems;)

> in here three stripped down snippets which hopefully allow you to see
> how things work, but you can always see exactly what we're doing by
> looking at our git repo, here:
>
> http://www.paraview.org/gitweb?p=ParaView.git;a=tree
>
> But stuff is kind of spread around in there, so don't feel you have to
> spend time browsing around. I'm just putting it out there in case...
>
> So the basic idea is we try to allow people to come up with their own
> ApplicationSessions which can compose any of the "protocols" we have
> already defined (not to be confused with the Autobahn protocol package).
> These "protocols" are classes which can export any number of rpc
> methods each, and by mixing and matching them, people should be able to
> come up with their own custom server application which exports exactly
> the rpc methods they need.

Let's first get basic stuff working and come back to this later. I'm not
sure I get what you want to do here ..

>
> Our class that extends ApplicationSession, "ServerProtocol", can be
> extended by anyone who wants to write their own server application:
>
> class ServerProtocol(ApplicationSession):
>
> def __init__(self, authdb=None):
> ApplicationSession.__init__(self, types.ComponentConfig(realm =

This is the problem. I suspected this .. hence I asked about the
constructor and call of base constructor;)

Crossbar.io will instantiate your ServerProtocol providing a
ComponentConfig .. not something you expect in authdb.

This is part of the interface contract of ApplicationSession.

If you want to override the constructor of ApplicationSession, the
correct way is:

def __init__(self, config):
ApplicationSession.__init__(self, config)
## do other initialization stuff

You can't pass in authdb (whatever that is). How would Crossbar.io (or
any other ApplicationSession driver) know how to construct that?

What you can do is pass in "extra" configuration (from JSON config), and
by using that info, create the authdb thing inside __init__. Or later in
onJoin.

> def initApplication(self):
> """
> Let subclass optionally initialize a custom application in lieu
> of the default vtkWebApplication.
> """
> global application

Bad, bad. "global" should be removed from the Python language;)

> @exportRpc("application.exit")
> def exit(self):
> """RPC callback to exit"""
> reactor.stop()
>
> A "Protocol" class that can export any number of rpc methods, we have a
> lot of these classes (btw, we have imported "register" as "exportRpc" in
> this module for our own convenience):

This is confusing, since it was called exportRpc only in the old
AutobahnPython WAMPv1 ..

> So maybe these snippets let you see how we may have broken your expected
> model of registering rpc methods. And you can see how the string
> updateKey is a function I intended to be calling on our AuthDb,
> something I explained in another thread, and which I had thought could
> be ignored in this case, since it should not be used at all. Though it
> is present in the ServerProtocol constructor with a default value of
> None, and that is where the ComponentConfig constructor is invoked.
>

The problem at hand is like above.

To give you advice on how to do better, I'd need to understand what you
are actually trying to achieve - means, what's the end _goal_. In high
level description.

Talking about the current code and reverse engineer your actual goals is
time consuming. But I'm confident we find a "clean" way ..

Cheers,
/Tobias


Scott Wittenburg

unread,
Aug 27, 2014, 5:02:43 PM8/27/14
to autob...@googlegroups.com
Hi Tobias,

   Ok, overriding the ApplicationSession constructor the correct way has resolved all the problems I was seeing.  Now both configurations seem to work fine, crossbar can run our existing server in either case, and our existing javascript client works with almost no changes, which is fantastic!  Thanks for helping me figure this out, sorry I brought in too much information last time when all you needed was to see the constructor.

   The one thing I had to change on the javascript client was to remove the authentication properties from the autobahn.Connection() constructor configuration object.  Is there some simple way we can tell crossbar (via our config.json or some file on the side) about a single user name and password that the client can then use to connect via wampcra authentication?

   Since you're so helpful, you can look forward to some more of my questions on the list in the next few days :-)  But I'm really excited to have things working so well already, and thank you for all the time you have spent so far!

Cheers,
Scott

Tobias Oberstein

unread,
Aug 28, 2014, 3:54:49 AM8/28/14
to autob...@googlegroups.com
Hi Scott,

> Ok, overriding the ApplicationSession constructor the correct way
> has resolved all the problems I was seeing. Now both configurations
> seem to work fine, crossbar can run our existing server in either case,
> and our existing javascript client works with almost no changes, which
> is fantastic! Thanks for helping me figure this out, sorry I brought in

Great! I'm glad you got it working. Thank's for your patience!

Looking back at our conversation and what was needed to solve the
problem, it's clear - again - that 2 areas that need improvement are:

- docs
- logging

I filed tickets for those:

https://github.com/crossbario/crossbar/issues/110
https://github.com/crossbario/crossbar/issues/111

> too much information last time when all you needed was to see the
> constructor.

np. better more than not enough ..

>
> The one thing I had to change on the javascript client was to remove
> the authentication properties from the autobahn.Connection() constructor
> configuration object. Is there some simple way we can tell crossbar
> (via our config.json or some file on the side) about a single user name
> and password that the client can then use to connect via wampcra
> authentication?

There are still some bits left to hook WAMP-CRA into Crossbar .. I do
that in the coming days and come back to you.

>
> Since you're so helpful, you can look forward to some more of my
> questions on the list in the next few days :-) But I'm really excited

Yes, please!

> to have things working so well already, and thank you for all the time
> you have spent so far!

I am happy that you already see where Crossbar can bring benefits to
your applications and systems. The ability for flexible component
deployment - without changing a single line of app code - is one of those.

/Tobias
> --
> 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/ad4bcafc-ece0-40d1-8d65-73e69ff81b3c%40googlegroups.com
> <https://groups.google.com/d/msgid/autobahnws/ad4bcafc-ece0-40d1-8d65-73e69ff81b3c%40googlegroups.com?utm_medium=email&utm_source=footer>.

Scott Wittenburg

unread,
Aug 28, 2014, 1:39:55 PM8/28/14
to autob...@googlegroups.com
Hi Tobias,


On Thursday, August 28, 2014 1:54:49 AM UTC-6, Tobias Oberstein wrote:
Hi Scott,

 >     Ok, overriding the ApplicationSession constructor the correct way
> has resolved all the problems I was seeing.  Now both configurations
> seem to work fine, crossbar can run our existing server in either case,
> and our existing javascript client works with almost no changes, which
> is fantastic!  Thanks for helping me figure this out, sorry I brought in

Great! I'm glad you got it working. Thank's for your patience!

Looking back at our conversation and what was needed to solve the
problem, it's clear - again - that 2 areas that need improvement are:

- docs
- logging

I filed tickets for those:

https://github.com/crossbario/crossbar/issues/110
https://github.com/crossbario/crossbar/issues/111

Sounds good, perhaps having those things would have helped me to figure out the problem without taking your time.  But I feel I should have probably caught that ApplicationSession constructor problem on my own anyway... sheesh.
 
> too much information last time when all you needed was to see the
> constructor.

np. better more than not enough ..

>
>     The one thing I had to change on the javascript client was to remove
> the authentication properties from the autobahn.Connection() constructor
> configuration object.  Is there some simple way we can tell crossbar
> (via our config.json or some file on the side) about a single user name
> and password that the client can then use to connect via wampcra
> authentication?

There are still some bits left to hook WAMP-CRA into Crossbar .. I do
that in the coming days and come back to you.

Ok, great.  For now, it seems that even if my javascript client requests wampcra authentication, if the server side isn't configured with any authentication, the connection is allowed to be made.  This is great for me at the current time, but is this the behavior you would expect?
 
>
>     Since you're so helpful, you can look forward to some more of my
> questions on the list in the next few days :-)  But I'm really excited

Yes, please!

> to have things working so well already, and thank you for all the time
> you have spent so far!

I am happy that you already see where Crossbar can bring benefits to
your applications and systems. The ability for flexible component
deployment - without changing a single line of app code - is one of those.

Yes, it's pretty awesome!  I was just fiddling around with my configs, and I got my application and router workers to run in separate crossbar nodes, which is so cool.

Thanks for being patient with me, Tobias, I really appreciate your help figuring out onJoin() problem!

Cheers,
Scott

 

Tobias Oberstein

unread,
Sep 1, 2014, 9:30:21 AM9/1/14
to autob...@googlegroups.com
Hi Scott,

> There are still some bits left to hook WAMP-CRA into Crossbar .. I do
> that in the coming days and come back to you.
>
> Ok, great. For now, it seems that even if my javascript client requests
> wampcra authentication, if the server side isn't configured with any
> authentication, the connection is allowed to be made. This is great for
> me at the current time, but is this the behavior you would expect?

Yes, that is expected, because:

- if you don't configure authentication in Crossbar.io it'll
automatically "authenticate" the client under role "anonymous"

- it'll authenticate the client under role "anyonymous" (using
authentication method "anonymous") _regardless_ what auth methods the
client was requesting

Whether that is really a good idea is a different question;)

https://github.com/crossbario/crossbar/issues/112

Please comment there if you like .. I'd be interested on what you think
the default/fallback behavior should be.

It's the old "secure by default" (anyone denied without explicit config)
vs the "works by default" (anyone allowed conveniently without explicit
config) philosophy question.

===

Anyway, if you modify your transport configuration for (note the empty
"auth" dictionary):

"transports": [
{
"type": "web",
"endpoint": {
"type": "tcp",
"port": 8080
},
"paths": {
"/": {
"type": "static",
"directory": ".."
},
"ws": {
"type": "websocket",
"auth": {
}
}
}
}
]

and connect a AutobahnJS client, you get

{reason: "wamp.error.not_authorized", message: "authentication using
method 'wampcra' denied by configuration", ..

in the connection close handler.

> I am happy that you already see where Crossbar can bring benefits to
> your applications and systems. The ability for flexible component
> deployment - without changing a single line of app code - is one of
> those.
>
> Yes, it's pretty awesome! I was just fiddling around with my configs,
> and I got my application and router workers to run in separate crossbar
> nodes, which is so cool.

Oh, yes. You can really build distributed systems without loosing your
mind;) And we'll get to yet another dimension as soon as we have
router-to-router, to build federations/clusters of routers.

Cheers,
/Tobias


Scott Wittenburg

unread,
Sep 2, 2014, 12:17:26 PM9/2/14
to autob...@googlegroups.com
Hi Tobias,


On Monday, September 1, 2014 7:30:21 AM UTC-6, Tobias Oberstein wrote:
Hi Scott,

>     There are still some bits left to hook WAMP-CRA into Crossbar .. I do
>     that in the coming days and come back to you.
>
> Ok, great.  For now, it seems that even if my javascript client requests
> wampcra authentication, if the server side isn't configured with any
> authentication, the connection is allowed to be made.  This is great for
> me at the current time, but is this the behavior you would expect?

Yes, that is expected, because:

- if you don't configure authentication in Crossbar.io it'll
automatically "authenticate" the client under role "anonymous"

- it'll authenticate the client under role "anyonymous" (using
authentication method "anonymous") _regardless_ what auth methods the
client was requesting

Whether that is really a good idea is a different question;)

https://github.com/crossbario/crossbar/issues/112

Please comment there if you like .. I'd be interested on what you think
the default/fallback behavior should be.

It's the old "secure by default" (anyone denied without explicit config)
vs the "works by default" (anyone allowed conveniently without explicit
config) philosophy question.

I personally take the view that things should work without extra effort.  Adding security should be what requires something extra.  But like you said, it's an age-old debate :-)

Thanks for your response!

Cheers,
Scott

 
Reply all
Reply to author
Forward
0 new messages