Designer to Gateway Communication (RPC)
When building a module with both Designer and Gateway components, it is often necessary to provide some sort of communication link between them. The project management system handles notifying the Gateway of resource changes, but for more dynamic communication, the RPC (remote procedure call) system is available.
The RPC system is easy to use, and works as follows:
In the Designer, the module uses GatewayConnectionManager.getInstance().getGatewayInterface().invoke(...) to send an invocation call to the Gateway for the provided module ID, with the given function name and parameters. invoke() uses the ClientRpcSerializer and RpcCall functions, in addition to int to get the timeout in milliseconds.
- ClientRpcSerializer is used by the Client side of an RPC call for serializing outgoing parameters and parsing the return value from the Gateway.
- RpcCall identifies the target function that is to be invoked using the moduleId, packageId, and the function name.
On the Gateway, the system looks up the module ID provided, and calls getRpcImplementation on its module hook.
The Gateway then reflectively locates the desired function, executes it, and returns the result.
Design Best Practice
Instead of calling GatewayInterface.invoke() yourself, you can pass your defined interface in a call to the GatewayConnection.getRpcInterface() method, which will create a dynamic proxy automatically. However, this method requires the interface class you pass in is annotated with @RpcInterface, to obtain a package ID.
Defining your functionality in an interface that is implemented by your RPC handler is a good idea in general, as you will have a single definition of what RPC functions are available.
For a list of reusable Ignition platform-level RPC proxy instances, see the PlatformRpcInstances class.
This paradigm is demonstrated below, with a simple function that sends someone’s name from the Designer to the Gateway to retrieve a greeting for them.
The RPC Interface - in the Common Package
@RpcInterface(packageId = "my-rpcmodule")
public interface MyRpcModule {
String getGreeting(String firstName);
}
The Gateway Implementation - in the Gateway Scope
public class MyRpcModuleImpl implements MyRpcModule {
@Override
public String getGreeting(String firstName){
return "Hello, " + firstName;
}
}
In the GatewayModuleHook
class MyModuleHook extends AbstractGatewayModuleHook {
@Override
public Optional getRpcImplementation() {
return Optional.of(
GatewayRpcImplementation.of(ProtoRpcSerializer.DEFAULT_INSTANCE, new MyModuleRpcImpl())
);
}
}
Using the getRpcInterface Method
private static final MyRpcModule RPC = GatewayConnection.getRpcInterface(
ProtoRpcSerializer.newBuilder().build();,
MyRpcConstants.MODULE_ID,
MyRpcModule.class
);