Search code examples
javascriptpythonautobahnwamp-protocol

Call procedure registered in javascript from python server Autobahn, Wamp


just started to use autobahn. I already did some examples and now I am trying to make my own server and client based on the tutorials.

I will use the autobahn for python for the server and the javascript library on the client side. At the moment I am struggling with the problem that I can only call procedures from the client to the server but not vice versa and I can only publish events from client side.

If I try to call the procedure I get following error

Failure: autobahn.wamp.exception.ApplicationError: 
ApplicationError('wamp.error.no_such_procedure', args = ("no procedure 
'com.myapp.add2client' registered",), kwargs = {})

So it seems the application is not registered, but on the client side it look like it does as I get an precedure id.

Procedure registered: 4026531820798724 

Can anyone point me in the right direction, please?

Client side

<script>

  var connection = new autobahn.Connection({
     url: 'ws://raspberrypi.local:8080',
     realm: 'realm1'
  });

    connection.onopen = function (session) {

       // 1) subscribe to a topic
       function onevent(args) {
          console.log("Event:", args[0]);
       }
       session.subscribe('com.myapp.hellofromserver', onevent);

       // 2) publish an event
       session.publish('com.myapp.hellofromclient', ['Hello, world!']);

       // 3) register a procedure for remoting
       function add2(args) {
          console.log("procedure called, result:", res);
          return args[0] + args[1];
       }
       session.register('com.myapp.add2client', add2).then(
           function (registration) {
              console.log("Procedure registered:", registration.id);
           },
           function (error) {
              console.log("Registration failed:", error);
           }
        );

       // 4) call a remote procedure
       session.call('com.myapp.add2server', [10, 10]).then(
          function (res) {
             console.log("Result:", res);
          }
       );
    };

    connection.open();

  </script>

Server side

 # Imports

   import sys


   from twisted.python import log
   from twisted.internet import reactor
   from twisted.internet.defer import inlineCallbacks
   from twisted.internet.endpoints import serverFromString

   from autobahn.wamp import router, types
   from autobahn.twisted.util import sleep
   from autobahn.twisted import wamp, websocket

   class MyBackendComponent(wamp.ApplicationSession):

   def onConnect(self):
      self.join("realm1")


   @inlineCallbacks
   def onJoin(self, details):


      # 1) subscribe to a topic
      def onevent(msg):
         print("Got event: {}".format(msg))

      yield self.subscribe(onevent, 'com.myapp.hellofromclient')

      # 2) publish an event
      self.publish('com.myapp.hellofromserver', 'Hello, world!')

      # 3) register a procedure for remoting
      def add2(x, y):
         return x + y

      self.register(add2, 'com.myapp.add2server');

      # 4) call a remote procedure
      res = yield self.call('com.myapp.add2client', 2, 3)
      print("Got result: {}".format(res))




   if __name__ == '__main__':

   ## 0) start logging to console
   log.startLogging(sys.stdout)

   ## 1) create a WAMP router factory
   router_factory = router.RouterFactory()

   ## 2) create a WAMP router session factory
   session_factory = wamp.RouterSessionFactory(router_factory)

   ## 3) Optionally, add embedded WAMP application sessions to the router
   component_config = types.ComponentConfig(realm = "realm1")
   component_session = MyBackendComponent(component_config)
   session_factory.add(component_session)

   ## 4) create a WAMP-over-WebSocket transport server factory
   transport_factory = websocket.WampWebSocketServerFactory(session_factory, \
                                                            debug = True, \
                                                            debug_wamp = False)

   ## 5) start the server from a Twisted endpoint
   server = serverFromString(reactor, "tcp:8080")
   server.listen(transport_factory)

   ## 6) now enter the Twisted reactor loop
   reactor.run()

Exception

    Unhandled error in Deferred:
Unhandled Error
Traceback (most recent call last):
Failure: autobahn.wamp.exception.ApplicationError: ApplicationError('wamp.error.no_such_procedure', args = ("no procedure 'com.myapp.add2client' registered",), kwargs = {})
Got event: Hello, my dear server!

THANKS A LOT!


Solution

  • At the time the backend component connects to the router and tries to call com.myapp.add2client, the client (browser) is not yet connected, and hence the procedure is not yet registered.

    If you run both your front- and your backend component against an independently running WAMP router, you can control the order of component start. If you run your backend component along an embedded router (as you do), then your backend component will start earlier than any frontend component that might connect.