The .NET framework uses Channel
Objects to connect Applications together. The two Channels which are available
right now in the .NET framework are the System.Runtime.Remoting.Channels.TCP
and the System.Runtime.Remoting.Channels.HTTP
classes.
The TCP channel is very close to
DCOM and will provide the highest performance. It will typically be used to
communicate between Applications on an Intranet environment. The HTTP channel
uses the HTTP protocol to enable applications to communicate over the Internet.
I will illustrate this by
developing a Command-Line based Publish-Subscribe Bulletin-Board Server and
Client that keeps a list of messages send by multiple clients.
Develop the Bulletin-Board Application
Messages that are sent from the
client reach the Server which saves them in an internal ArrayList.
These messages can at any time be retrieved from the Server.
1. Develop The Chat Server Application : Server
Experiment with using both the TCP Channels and
the HTTP Channels in the Server Code.
////////////////////////////////////////////////////// /// The following example shows a Distributed Component /// developed using C# and the .NET Framework. /// /// author:
Gopalan Suresh Raj /// Copyright (c), 2002. All Rights Reserved. /// URL:
https://gsraj.tripod.com/ /// email:
gopalan@gmx.net /// ////////////////////////////////////////////////////// using System; // Import the Remoting API support using System.Runtime.Remoting; using System.Runtime.Remoting.Channels; using System.Runtime.Remoting.Channels.Http; // Import Collections support using System.Collections;
namespace Topic { /// <summary> /// A Bulletin Board Server that buffers messages /// </summary> public class Topic :
MarshalByRefObject {
/// <summary> /// Buffers the messages on the Bulletin Board Server /// </summary> ArrayList messageList_ = new ArrayList();
/// <summary> /// Adds a new message to the Bulletin Board Server /// </summary> /// <param name="message">New message to be buffered</param> public void addMessage( string clientID, string message ) { messageList_.Add( message ); Console.WriteLine( "From ClientID :" + clientID + ", Message Added :" + message ); }
/// <summary> /// Retrieves all messages stored on the Server /// </summary> /// <returns>All messages, each concatenated by new line characters</returns> public string retrieveAllMessages(string clientID) { string messages = null; foreach ( string message in messageList_ ) { messages += message+"\n"; } return messages; }
/// <summary> /// Displays on console any string thats pased as a parameter /// </summary> /// <param name="info">string to be displayed</param> /// <returns>string that was displayed</returns> public string displayMessage( string clientID, string info ) { Console.WriteLine( info ); return info; } }
/// <summary> /// The Server class implementation /// </summary> public class TheServer {
/// <summary> /// Entry Point into this application /// </summary> public static void Main() { int listeningChannel = 1099; // Create a New HTTP Channel that listens on Port listeningChannel // TcpChannel channel = new TcpChannel( listeningChannel ); HttpChannel channel =
new HttpChannel( listeningChannel ); // Register the channel with the runtime ChannelServices.RegisterChannel( channel ); // Expose the Calculator Object from this Server RemotingConfiguration.RegisterWellKnownServiceType(
typeof( Topic ), "Topic", WellKnownObjectMode.Singleton ); // Keep the Server running until the user presses enter Console.WriteLine( "The Topic Server is up and running on port {0}", listeningChannel ); Console.WriteLine( "Press enter to stop the server..." ); Console.ReadLine(); } } }
2. Develop the Bulletin-Board Client Application
: Client
In the Client Application on Line 30, The "Topic"
URI is used by the Client to identify the Server that it wanted to connect to.
This matches up with the URI parameter to the RemotingServices.RegisterWellKnownServiceType()
on line 78 in the Server code. Please be
aware that the HTTP
Channel is using soap formatted messages.
////////////////////////////////////////////////////// /// The following example shows a Distributed Component /// Client developed using C# and the .NET Framework. /// /// author:
Gopalan Suresh Raj /// Copyright (c), 2002. All Rights Reserved. /// URL:
https://gsraj.tripod.com/ /// email:
gopalan@gmx.net /// /// <compile> /// csc /r:TopicServer.exe TopicClient.cs /// </compile> /// <usage> /// TopicClient port /// </usage> ////////////////////////////////////////////////////// using System; // Import the Remoting API support using System.Runtime.Remoting; using System.Runtime.Remoting.Channels; using System.Runtime.Remoting.Channels.Http; // Use the Topic namespace using Topic;
namespace Topic { /// <summary> /// The Client to a Distributed Bulletin Board Server /// </summary> class TopicClient { static void Main(string[] args) {
int listeningChannel = Int32.Parse( args [0] ); // Create and register a channel to communicate to the server // The Client will use the port passed in as args to listen for callbacks HttpChannel channel =
new HttpChannel( listeningChannel ); ChannelServices.RegisterChannel( channel );
// Create an instance on the remote server and call a method remotely Topic topic = (Topic) Activator.GetObject(
typeof ( Topic ), // type to create "http://localhost:1099/Topic" // URI ); if (topic == null) { Console.WriteLine( "Unable to obtain a Reference to the Remote Topic Server component ..." ); return; } // Create a unique Client ID string clientID = Guid.NewGuid().ToString(); string message = "New Client ID: "+clientID+", Connected From Port "+listeningChannel; // Invoke a method from the Server and display the returned value Console.WriteLine(
topic.displayMessage( clientID, message
) ); while (message.ToLower().StartsWith( "quit" ) == false) { Console.WriteLine( "Enter a Message to Add to Server, 'quit' to exit application" ); message = Console.ReadLine(); topic.addMessage( clientID, message
); } Console.WriteLine( "The Messages Are:" +
topic.retrieveAllMessages( clientID
) ); topic.displayMessage( clientID, "Client "+ clientID + ": Connected From Port "+listeningChannel+ ", Terminating..." ); }
} }
3. Compile the Server and the Client
Applications
Command Prompt
C:\MyProjects\Cornucopia\Remoting\Topic>csc /debug+ /r:system.runtime.remoting.dll
TopicServer.cs Microsoft (R) Visual C# Compiler Version 7.00.9254 [CLR
version v1.0.2914]
Copyright (C) Microsoft Corp 2000-2001. All rights reserved.
C:\MyProjects\Cornucopia\Remoting\Topic>
C:\MyProjects\Cornucopia\Remoting\Topic>csc /debug+ /r:TopicServer.exe /r:system.runtime.remoting.dll
TopicClient.cs Microsoft (R) Visual C# Compiler Version 7.00.9254 [CLR
version v1.0.2914]
Copyright (C) Microsoft Corp 2000-2001. All rights reserved.
C:\MyProjects\Cornucopia\Remoting\Topic>
4. Run One Instance of the Server (TopicServer.EXE)
and Multiple Instances of the Client (TopicClient.EXE)
Remember to be connected to the Internet if
you're using the HTTPChannel.