This is driving me crazy.
I finally got the Remoting sample chat application working almost.
When I run the chat client in VS.NET it goes into an endless loop --
that's because I assume that there is now way for me to interface to a
Console.ReadLine().
However, when I run it in the cmd window, it does not output any
Console.WriteLine()s ( even the "Hello" that I put as the first
statement in Main() ). Nothing prints to the command line!?!
ChatClient.exe definitely loads and is 'running' because I see it in
Task Manager! I can even run as many instances as I want...but none
are printing to the command line.
How can it just skip doing the Console.WriteLine() ???
Here is the code:
// ChatClient.cs
using System;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Http;
public class ChatClient
{
private string _alias = null;
public ChatClient(string alias)
{
this._alias = alias;
}
public void Run()
{
RemotingConfiguration.Configure("ChatClient.exe.co nfig");
// Create a proxy to the remote object.
ChatCenter chatcenter = new ChatCenter();
// Create a remotely delegatable object
MyCallbackClass callback = new MyCallbackClass (_alias) ;
// Create a new delegate for the method that you want the event to call
// when it occurs on the server. The SubmissionReceiver method will
// then be a remote call for the server object; therefore, you must
// register a channel to listen for this call back from the server.
chatcenter.Submission += new
SubmissionEventHandler(callback.SubmissionCallback );
String keyState = "";
while (true)
{
Console.WriteLine("Press 0 (zero) and ENTER to Exit:\r\n");
keyState = Console.ReadLine();
if (String.Compare(keyState,"0", true) == 0)
break;
// Call the server with the string you submitted and your alias.
chatcenter.Submit(keyState, _alias);
}
chatcenter.Submission -= new
SubmissionEventHandler(callback.SubmissionCallback );
}
// Args[0] is the alias that will be used.
public static void Main(string[] Args)
{
//this hello does not print
Console.WriteLine("hello");
if (Args.Length != 1)
{
Console.WriteLine("You need to type an alias.");
return;
}
else
{
Console.WriteLine("running...");
}
ChatClient client = new ChatClient(Args[0]);
//= new ChatClient("john");
client.Run();
}
}
// MyCallbackClass is the class that contains the callback function to
// which ChatClient will submit a delegate to the server.
// To to pass a reference to this method (that is, a delegate)
// across an application domain boundary, this class must extend
// MarshalByRefObject or a class that extends MarshallByRefObject like all
// other remotable types. MyCallbackClass extends
RemotelyDelegatableObject because
// RemotelyDelegatableObject is a class that the server can obtain type
information
// for.
class MyCallbackClass : RemotelyDelegatableObject
{
private string _alias = null;
public MyCallbackClass () {}
public MyCallbackClass (string alias) { _alias = alias ; }
// InternalSubmissionCallback is the method that is called by
// RemotelyDelegatableObject.SubmissionCallback(). SubmissionCallback() is
// sent to the server via a delegate. You want the chat server to call
// when the Submission event occurs -- even if the submission is yours.
// The SubmissionEventHandler delegate wraps this function and is passed
// to the Add_Submission (SubmissionEventHandler delegate) member of
// the ChatCoordinator object. The .NET Remoting system handles the transfer
// of all information about the client object and channel necessary to
// make a return remote call when the event occurs.
protected override void InternalSubmissionCallback (object sender,
SubmitEventArgs submitArgs)
{
// Block out your own submission.
// This simple chat server does not filter anything.
if (String.Compare(submitArgs.Contributor, _alias, true) == 0)
{
Console.WriteLine("Your message was broadcast.");
}
else
Console.WriteLine(submitArgs.Contributor
+ " says:\r\n"
+ new String('-', 80)
+ submitArgs.Contribution
+ "\r\n"
+ new String('-', 80)
+ "\r\n");
}
// This override ensures that if the object is idle for an extended
// period, waiting for messages, it won't lose its lease. Without this
// override (or an alternative, such as implementation of a lease
// sponsor), an idle object that inherits from MarshalByRefObject
// may be collected even though references to it still exist.
public override object InitializeLifetimeService()
{
return null;
}
}