WebReference.com - Part 3 of Chapter 6: Professional C# Web Services, from Wrox Press Ltd (4/5)
[previous] [next] |
Professional C# Web Services
Sending MBR Objects to the Server
Sending marshal-by-value objects from the client to the server is very similar to sending them in the other direction, but what about sending a remotable object to the server? How does the server come back to the client?
Instead of showing the derivation of MarshalByRefObject in this picture, I've
introduced a stereotype <<remotable>> to make it easier to read. We can see
<<remotable>> as indicating inheritance from MarshalByRefObject.
The MBR class B will be instantiated from the client, and passed with the method SetB()
to the remote object MyRemoteObject. The remote object will use the object that was
instantiated on the client across the network:

Let's add two methods to the remote object class in the file MyRemoteObject.cs. With the
method SetB() the client can pass a remotable object of type B to the server.
The method SetB() accepts an object of class B. In the last section we created
class B so that it derives from MarshalByRefObject, so the object will not be
copied but a proxy will be created instead. The method SetB() stores the reference to the
proxy of B in the field b. The method UseB() uses the field
b to call the property Data and passes the value returned to the client.
public class MyRemoteObject : System.MarshalByRefObject
{
public MyRemoteObject()
{
Console.WriteLine("MyRemoteObject Constructor called");
}
private B b;
public void SetB(B b)
{
Console.WriteLine("SetB called");
this.b = b;
}
public int UseB()
{
Console.WriteLine("UseB called");
return b.Data;
}
// ...
One important thing to note here is that the class
MyRemoteObjectnow has state. Using this class as a well-known object would result inbbeing set tonullwith every method call, soUseB()wouldn't work. This remote object class can only be used in client-activated object configurations.
The client can be changed to call the remote object. In the client code, we create a new instance
of the class B and initialize it with the value 44. While obj is
instantiated remotely with the new operator, b is created locally because the class B
is not listed in the client configuration file, but the class MyRemoteObject is. Accessing the
Data property merely performs a local call:
// SimpleClient.cs
class SimpleClient
{
static void Main(string[] args)
{
RemotingConfiguration.Configure("SimpleClient.exe.config");
MyRemoteObject obj = new MyRemoteObject(333);
obj.Hello();
B b = new B(44);
// This is a local call!
int b1 = b.Data;
When calling SetB() with MyRemoteObject, we pass a reference to
b to the server. Because B is derived from MarshalByRefObject
a reference can be passed. Next we call the UseB() method where this reference is used
within the server. The remote object will try to access the object that is running in the client
process:
// Pass a reference to the object running in the client
// to the server
obj.SetB(b);
// Use the object in the client from the server
b1 = obj.UseB();
To run this application we have to use a bi-directional channel. Because the client application
now has to act both as a client to call methods in the remote object, and as a server where the
instance b is invoked from the server, we must use the TcpChannel that
can do both. If we use the wrong channel, the result will be a RemotingException with
the following error message:
The remoting proxy has no channel sinks which means either the server has no registered server channels that are listening, or this application has no suitable client channel to talk to the server.
Be sure to specify a reference to the channel tcp in both the client and server
configuration files as we did earlier instead of tcp client and tcp server.
Running the server and client application, we get this output in the client:

The first time we see the output of the B.Data is when we access this property
locally. The second output we see is when a method of the object running in the client is invoked
from the server by calling obj.UseB() in the client application.
[previous] [next] |
Created: March 26, 2002
Revised: March 26, 2002
URL: http://webreference.com/programming/csharp/webservices/chap6/3/4.html

Find a programming school near you