Using Messaging API For Remote Code Execution

Messaging API gives you an easy and powerful tool for remote code execution. The short overview of the API is in Messaging chapter.

All you will need to do is to define specific message class or classes (should be shared between client and server).

The client side can issue messages using:

c#: IMessageSender#Send(message)

VB: IMessageSender#Send(message)

The server side should register a message listener:

c#: Configuration#SetMessageRecipient(IMessageRecipient)

VB: Configuration#SetMessageRecipient(IMessageRecipient)

Message recipient should define a response to the different messages received in

c#: ProcessMessage(IObjectContainer objectContainer, object message)

vb: ProcessMessage(ByVal objectContainer As IObjectContainer, ByVal message As Object)

method. ObjectContainer parameter gives full control over the database.

Let's reset our database and try updating using special UpdateServer message.

RemoteExample.cs: SetObjects
01public static void SetObjects() 02 { 03 File.Delete(YapFileName); 04 IObjectContainer db = Db4oFactory.OpenFile(YapFileName); 05 try 06 { 07 for (int i = 0; i < 5; i++) 08 { 09 Car car = new Car("car"+i); 10 db.Set(car); 11 } 12 db.Set(new RemoteExample()); 13 } 14 finally 15 { 16 db.Close(); 17 } 18 CheckCars(); 19 }
RemoteExample.cs: UpdateCarsWithMessage
01public static void UpdateCarsWithMessage() 02 { 03 IObjectServer server=Db4oFactory.OpenServer(YapFileName,0); 04 // create message handler on the server 05 server.Ext().Configure().SetMessageRecipient( 06 new UpdateMessageRecipient()); 07 try 08 { 09 IObjectContainer client=server.OpenClient(); 10 // send message object to the server 11 IMessageSender sender = client.Ext().Configure().GetMessageSender(); 12 sender.Send(new UpdateServer()); 13 client.Close(); 14 } 15 finally 16 { 17 server.Close(); 18 } 19 CheckCars(); 20 }

RemoteExample.vb: SetObjects
01Public Shared Sub SetObjects() 02 File.Delete(YapFileName) 03 Dim db As IObjectContainer = Db4oFactory.OpenFile(YapFileName) 04 Try 05 Dim i As Integer 06 For i = 0 To 5 - 1 Step i + 1 07 Dim car As Car = New Car("car" + i.ToString()) 08 db.Set(car) 09 Next 10 db.Set(New RemoteExample()) 11 Finally 12 db.Close() 13 End Try 14 CheckCars() 15 End Sub
RemoteExample.vb: UpdateCarsWithMessage
01Public Shared Sub UpdateCarsWithMessage() 02 Dim server As IObjectServer = Db4oFactory.OpenServer(YapFileName, 0) 03 ' create message handler on the server 04 server.Ext().Configure().SetMessageRecipient(New UpdateMessageRecipient()) 05 Try 06 Dim client As IObjectContainer = server.OpenClient() 07 ' send message object to the server 08 Dim sender As IMessageSender = client.Ext().Configure().GetMessageSender() 09 sender.Send(New UpdateServer()) 10 client.Close() 11 Finally 12 server.Close() 13 End Try 14 CheckCars() 15 End Sub

You can also put some information in the message being sent (UpdateServer class).

The advantage of this method is that having predefined message types you can make any changes to the handling code only on the server side. In the situations with many distributed clients it can really save you lots of time on support.