Transfering message to other brunet nodes using RPC
From Grid-Appliance Wiki
Contents |
Intorduction
Before staring this section, if you are not familiar with Brunet, you can refer to Brunet page first. This page shows a way to use IRpcHandler to send rpc call to the local brunet end point and forward the rpc call to other brunet end points in the same brunet node. We can regard this rpc hander as running in server and client mode.
Compiling and running
Compile using existing library
You can download library and source code here. You should compile "HelloWorldRpcSCHandler.cs" with Brunet.dll and BrunetApp.dll files.
For example, you can type "gmcs -r:Brunet.dll,BrunetApp.dll HelloWorldRpcSCHandler.cs" in the colsole. You can also use mono compiler other than "gmcs".
Compile using your own brunet source code
If you want to use your brunet source code, you should create a folder under Applications directory, and copy HelloWorldRpcSCHandler.cs and default.build files to the directory.
For example, create folder "HelloWorld" under the Brunet-Application directory (i.e.,brunet/src/Brunet/Applications/HelloWorld/), and copy two files to (brunet/src/Brunet/Applications/HelloWorld/). Run "nant" in the directory, and new executable will reference your own brunet source code.
If you have compile problem, you can download new version of brunet soucre code here
Running the application
1. Run HelloWorldRpcSCHandler.exe with input argument local.config (Linux: mono HelloWorldNodeDataHandler local.config, Windows: HelloWorldNodeDataHandler.exe local.config)
2. Run another HelloWorldRpcSCHandler.exe file with local.config
- If you run multiple applications in one machine, you should change XmlRpcManager Port number element in the configuration file to avoid port number confliction.
3. Type the brunet address of end point which you initiated in step 2 at the console of brunet end point which you initiated in step 1.
4. Run python command shell. Type command as follows.
>>> import sys,xmlrpclib >>> rpc=xmlrpclib.Server("http://127.0.0.1:10000/xm.rem") >>> print rpc.localproxy("HwRpc.Test",xmlrpclib.Binary("Hello World")) Hello World >>>
- Here, you should be careful for the local host port number(127.0.0.1:10000). The port number should be same as XmlRpcManager Port number element at the local.config file.
- HelloWorldRpcSCHandler sends the first input argument back as a result for rpc call. Thus, You should insert at least one argument for the rpc call to get correct result.
5. You can see the result at the application console as well as the python command shell.
- If you want to forward the rpc call to many other brunet end points, repeat step 2-3.
Operation sequence
In this section, you will see how rpc handler works as server and client function.
Rpc forwarding procedure
1. Register rpc forwarding end point. In this picture, "Brunet:node:cccccccccc" and "Brunet:node:eeeeeeeeee" are registered for rpc forwarding end point.
2. User commands "HwRpc.Test" rpc using python.
3. The rpc is processed at the "HwRpc" handler. At the above picture, the rpc is forwarded to "HW" handler of registered end points.
4. End points which receive the rpc through "HW" handler return the result back to the caller's "HwRpc" handler.
How to implement
1. Define two RpcHandler("HwRpc" and "HW" handler), and register the handler to the RpcManager.
public class HelloWorldRpcHandler : BasicNode, IRpcHandler{ public override void Run() { _app_node = CreateNode(_node_config); _node.Rpc.AddHandler("HwRpc", this); } } public class HelloWorldDataHandler : IRpcHandler{ public HelloWorldDataHandler(Node node){ _node = node; _node.Rpc.AddHandler("HW", this); } }
2. If user commands "rpc.localproxy("HwRpc.Test",xmlrpclib.Binary("Hello World"))", this rpc call is first handled at the HwRpc handler. HwRpc handler creates return channel to receive rpc call result, and forward the rpc call using "RpcManager.Invoke()" method. If rpc result comes from other p2p end point, it send the result back to the user using "RpcManager.SendResult()" method.
public void HandleRpc(ISender caller, string method, IList arguments, object request_state){ Channel returns = new Channel(1); returns.CloseEvent += delegate(object o, EventArgs eargs) { RpcResult result; result = (RpcResult)returns.Dequeue(); _node.Rpc.SendResult(request_state, result.Result); }; _node.Rpc.Invoke(sender, returns, "HW.Test", key); }
3. End point which receives rpc call through "HW" rpc hanler, simply returns the first argumet using the return channel.
public void HandleRpc(ISender caller, string method, IList arguments, object request_state){ _node.Rpc.SendResult(request_state, arguments[0]); }


