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!
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.