Here is an example of using a channel. In this example, we can see that using HTTP channel to put two applications
The connection is so simple. The following server applications provide a service that reverses the alphabetic order of a string.
Server. cs using System;
Using System. IO;
Using System. Runtime. Remoting;
Using System. Runtime. Remoting. Channels. HTTP;
Namespace RemotingSample
{
Public class Reverser: MarshalByRefObject
{
Public string Reverse (string text)
{
Console. WriteLine ("Reverse ({0})", text );
String rev = "";
For (int I = text. Length-1; I> = 0; I --)
{
Rev + = text [I];
}
Console. WriteLine ("returning: {0}", rev );
Return rev;
}
}
Public class TheApp
{
Public static void Main ()
{
File: // Create a new HTTP channel that
// Listens on port 8000
HTTPChannel channel = new HTTPChannel (8000 );
// Register the channel with the runtime
ChannelServices. RegisterChannel (channel );
// Expose the Reverser object from this server
RemotingServices. RegisterWellKnownType (
"Server", // assembly name
"RemotingSample. Reverser", // full type name
"Reverser. soap", file: // URI
WellKnownObjectMode. Singleton // instancing mode
);
// Keep the server running
// The user presses enter
Console. WriteLine ("Server.exe ");
Console. WriteLine ("Press enter to stop server ...");
Console. ReadLine ();
}
}
}
Now we have a character reverse service. We will create a customer application to use this service:
Client. cs using System;
Using System. Runtime. Remoting;
Using System. Runtime. Remoting. Channels. HTTP;
Using RemotingSample; // reference the server
Public class TheApp
{
Public static void Main ()
{
// Create and register a channel
// To comunicate to the server.
// The client will use port 8001
// To listen for callbacks
HTTPChannel channel = new HTTPChannel (8001 );
ChannelServices. RegisterChannel (channel );
// Create an instance on the remote server
// And call a method remotely
Reverser rev = (Reverser) Activator. GetObject (
Typeof (Reverser), // type to create
& Quot; http: // localhost: 8000/Reverser. soap & quot; file: // URI
);
Console. WriteLine ("Client.exe ");
Console. WriteLine (rev. Reverse ("Hello, World! "));
}
}
See how easy it is to connect two applications together through remote. NET. When the server and client programs are placed on two different machines, we can make both programs run on port 80. In this way, remote calls can be implemented through a firewall. You can also change HTTPChannel to a TCPChannel.
You should note that the client uses "Reverser. soap" to identify the object to be connected. This name matches the URI parameter of RegisterWellKnownType in the server code. The extension of ". soap" is unnecessary. A URI can be any string, as long as it uniquely identifies a server object. The extension of ". soap" is only used to remind us that the HTTP channel uses soap to format information.
In the above channel example, you may have the question: how is the parameter transmitted across the network and how is the return value returned? The answer is that parameters must be serialized before they are transmitted across networks. All objects or structures to be transferred must be processed in this way. The serialization process is simple. It only creates a continuous copy of the variable or the data in the object in bytes. Restoring these bytes to a value or processing an object instance is called deserialization.
How are parameters serialized? The remote. NET architecture provides us with an object set called formatters. The formatter can convert an object into a specific continuous data format or restore it back .. NET provides two formats for us:
System. Runtime. Serialization. Formatters. Binary
System. Runtime. Serialization. Formatters. SOAP
Binary format is the simplest. It directly converts data into a byte stream. The SOAP formatter uses an XML file to maintain an object data. To learn more about SOAP, go to the http://www.soapwebservices.com.
The following is a simple example of a formatter. We will use the SOAP formatter, because it uses XML, we can easily read serialized data.
Soap. cs using System;
Using System. IO;
Using System. Runtime. Serialization. Formatters. Soap;
Public class Person
{
Public string FirstName = "David ";
Public string LastName = "Findley ";
Private int Age = 29;
}
Public class TheApp
{
Public static void Main ()
{
Stream stream = File. Create ("example. xml ");
SoapFormatter formatter = new SoapFormatter ();
Person p = new Person ();
// Persist an integer
Formatter. Serialize (stream, 5 );
File: // persist a string
Formatter. Serialize (stream, "This is a string ");
// Persist an object
Formatter. Serialize (stream, p );
Stream. Close ();
}
}
For each serialized call, the content of example. xml has three different parts:
Example. xml
SOAP-ENV: Body>
<Xsd: int id = "ref-1">
<M_value> 5 </m_value>
</Xsd: int>
SOAP-ENV: Body>
SOAP-ENV: Body>
<SOAP-ENC: string id = "ref-1"> This is a string </SOAP-ENC: string>
SOAP-ENV: Body>
SOAP-ENV: Body>
<A1: Person id = "ref-1">
<FirstName id = "ref-3"> David </FirstName>
<LastName id = "ref-4"> Findley </LastName>
<Age> 29 </Age>
</A1: Person>
SOAP-ENV: Body>
As you can see, it serializes basic value classes and objects. HTTPChannel uses the SOAP formatter to transmit data between the client and the server.
In general, the formatter can format and maintain the data of values or objects. Channel transmits and receives data. Through the collaboration between the channel and the formatter, we can use any network and protocol to connect two applications.