Remote function calls (RPC, remote procedure call)
Creating a remotely-callable function
In the Webapp class, a remotely-callable function can be defined by using the @rpc
decorator.
Server-side
Remotely-callable functions defined in the server must be prefixed by server_
.
Their first argument is always the session object (which is None if there is no session), and additional arguments
are allowed.
Here is an example:
class MyWebApp(ServerSideWebapp):
def __init__(self):
[...]
@rpc # Mark the function as remotely callable by the client
def server_remote_function(self, session, argument1, argument2):
return argument1 + argument2
Client-side
Remotely-callable functions defined in the client are supported only if you use WebSockets;
they must be prefixed by client_
. Contrary to server ones, they have no session argument.
Here is an example:
class MyWebApp(ClientSideWebapp):
def __init__(self):
[...]
@rpc # Mark the function as remotely callable by the server
def client_remote_function(self, argument1, argument2):
return argument1 + argument2
Calling a remote function
When calling a a remotely-callable function, the first argument is always a callback function
that will be called with the returned value.
You may pass None
as callback if you don’t need the returned value.
Client-side
In the client, remotely-callable server functions can be called directly on the webapp.
Here are examples, with and without callback:
def done(response):
print(response)
webapp.server_remote_function(done, 2, 3)
webapp.server_remote_function(None, 2, 3)
Server-side
In the server, remotely-callable client functions can be called at three levels:
directly on the webapp: in that case, the function is executed for all connected clients.
on a Session object: in that case, the function is executed for the corresponding client.
on a Group object: in that case, the function is executed for all clients in that Group.
Here are examples:
def done(response):
print(response)
webapp.client_remote_function(done, 2, 3)
session.client_remote_function(done, 2, 3)
group.client_remote_function(done, 2, 3)
Serialization and supported datatypes
FullPy uses its own object serializer for serializing remote functions arguments and return values. It supports all basic Python datatypes (including int, float, str, tuple, list and dict) and can be extended for serializing Python objects and/or OWL ontology entities. It produce a JSON compatible serialization if the encoded data is JSON compatible; however, it also supports non-JSON feature, such as Python tuples and dictionaries with non-string keys.
For more information on the serializer, please refer to Sessions.
WebSocket example
The two next subsections give an example of an Hello World FullPy web application with WebSocket (the code can be found in the “demo/demo_1_hello_world_websocket” directory of FullPy). We have already seen a similar ajax example (see Starting a new project with FullPy).
Hello World server example
from gevent import monkey
monkey.patch_all()
import sys, os, os.path
from fullpy.server import *
class MyWebApp(ServerSideWebapp):
def __init__(self):
ServerSideWebapp.__init__(self)
self.name = "demo"
self.url = "/index.html"
self.title = "FullPy demo"
self.static_folder = os.path.join(os.path.dirname(__file__), "static")
self.use_python_client(os.path.join(os.path.dirname(__file__), "client.py"))
self.use_websocket(debug = True)
@rpc # Mark the function as remotely callable by the client (RPC = remote procedure call)
def server_hello(self, session): # The name of server-side functions MUST starts with "server_"
def f():
gevent.sleep(2.0) # Wait 2 seconds
session.client_update_speech(None, "Goodbye!") # Call the client_update_speech() remote function on the client
gevent.spawn(f) # Execute f() in a separate "greenlet" microthread, in parallel
return "Hello world!"
from fullpy.server.gunicorn_backend import *
serve_forever([MyWebApp()], "http://127.0.0.1:5000")
Hello World client example
from fullpy.client import *
class MyWebApp(ClientSideWebapp):
def on_started(self, url_params):
def done(response):
html = HTML("""FullPy Demo loaded Ok! Server says: '<span id="server_speech">%s</span>'.""" % response)
html.show()
webapp.server_hello(done) # Call the server_hello() remote function on the server
@rpc # Mark the function as remotely callable by the server (RPC = remote procedure call)
def client_update_speech(self, text): # The name of client-side functions MUST starts with "client_"
html = HTML(text)
html.show(container = "server_speech") # Update the content of the "server_speech" HTML tag
MyWebApp()