Client-Server architecture
It is possible to use Rembus protocol to setup a simple client-server architecture without a decoupling broker.
In this scenario one component plays the role of a server that handles RPC requests and receives messages published by others components that play the role of clients.
NOTE Without a broker a pub/sub is a one-to-one communication pattern: components publish messages that are received by the server but they are not broadcasted to anyone else.
Below a minimal example of a component that exposes a service and accepts connections for others components and respond only to authenticated components:
using Rembus
function my_service(ctx, component, x, y)
## authorization barrier
# isauthenticated(component) || error("unauthorized")
return x+y
end
function start_server()
rb = server()
expose(rb, my_service)
serve(rb)
end
start_server()
Detailed description
The Server
The component that plays the server role is initialized as:
rb = server()
expose
, as usual, make methods available to RPC clients:
expose(rb, my_service)
The signature of my_service
must have a ctx
value as first argument and a component
value as second argument:
function mymethod(ctx, component, x, y)
return x + y
end
The ctx
argument is a global state object that is passed to the server constructor:
mutable struct Ctx
# state fields
end
ctx = Ctx()
rb = server(ctx)
If a global state is not needed by default ctx is set to nothing
:
rb = server()
expose(rb, "my_service")
#implies that ctx is nothing:
function my_function(ctx, component, x, y)
@assert ctx === nothing
end
The component
object if useful for:
- serving only authenticated components;
- storing component session state into
session(component)
dictionary;
serve
is the final step: the server starts and waits for connection requests from clients:
Rembus.serve(rb)
The Client
On the calling side the rpc method has to be invoked with two arguments:
@rpc my_service(x,y)