[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

microsoft.public.dotnet.framework.remoting

Do I need two remoting objects?

Chester West

7/21/2004 1:12:00 AM

Greetings Everyone -

I'm trying to do the following:

On one machine (let's call it the SERVER), I'm creating a object. Then
I'm exposing it
for remoting by executing a
System.Runtime.Remoting.RemotingServices.Marshal call.

On another machine (let's call it the CLIENT) I'm successfully getting a
instantiation of the
Remoting Object created on the SERVER. I can see the values of
properties.

Then, since the CLIENT is a C# application form, I attempt to establish
a reference within the
object so that I can perform processing (I.E., at the SERVER, I set
processing
parameters and a flag which in theory will cause an event to fire,
alerting the CLIENT
that processing needs to occur) by doing the following:

this.ServerAgent.SetFormReference(this)

where "this" is a reference to the CLIENT form. The "ServerAgent" is the
remoting object
created on the server. The "ServerAgent" then simply stores the
reference so that it can
perform processing.

Unfortunately, As soon as I attempt to execute the
"this.ServerAgent.SetFormReference(this)"
I get an exception. Something REALLY informative, like "the server has
caused an exception.
For more details turn on the ConfigErrors section in the configuration
file".

Of course, this is a C# application so I have no idea how to turn on the
items required to get the
details, since the ConfigErrors setting seems to refer to ASP.NET.

I suspect that since the form is running on the CLIENT that .NET cannot
resolve the call since it
is not running in the same process or something like that.

My questions are:
(1) Am I right in the assumption above?

(2) Do I need to create 2 remoting objects (1 on the SERVER, 1 on the
CLIENT) to
accomplish the ability for the server to tell the client to execute
commands.

if not, then what do I need to do to get this to function....It
shouldn't be "brain surgery"
to do this, but it seems like it is...

(3) How to set the configuration file to get additional information

Thanks


6 Answers

Sunny

7/21/2004 2:53:00 PM

0

Hi Chester,
read inline:

In article <OPsVu#rbEHA.2388@TK2MSFTNGP11.phx.gbl>, CWEST@Video-
mation.com says...
>
> this.ServerAgent.SetFormReference(this)
>
> where "this" is a reference to the CLIENT form. The "ServerAgent" is the
> remoting object
> created on the server. The "ServerAgent" then simply stores the
> reference so that it can
> perform processing.

This is bad idea. It is better to implement a simple wrapper class which
you can use to transfer the calls from the server to the client.

>
> Unfortunately, As soon as I attempt to execute the
> "this.ServerAgent.SetFormReference(this)"
> I get an exception. Something REALLY informative, like "the server has
> caused an exception.
> For more details turn on the ConfigErrors section in the configuration
> file".

The exception you see is because server have to have access to the
assembly of the client class, to which it is connected. In your
situation - the form. Thats why I sugested a wrapper. You can put this
wrapper class in a shared assembly and deploy it both with the client
and the server.

>
> Of course, this is a C# application so I have no idea how to turn on the
> items required to get the
> details, since the ConfigErrors setting seems to refer to ASP.NET.

it is not ConfigErrors, but customErrors. Note it is case sensitive. You
have to put it in a config file (customErrors = off). And read it from
your server app with RemotingConfiguration.Configure.

>
> I suspect that since the form is running on the CLIENT that .NET cannot
> resolve the call since it
> is not running in the same process or something like that.

Not the process, just the server knows nothing about your client class
(form). How do you expect to call something without knowing it?

>
> My questions are:
> (1) Am I right in the assumption above?

Partialy. I have filled the gaps :)

>
> (2) Do I need to create 2 remoting objects (1 on the SERVER, 1 on the
> CLIENT) to
> accomplish the ability for the server to tell the client to execute
> commands.

Yes, you have. Usualy, when I need a callbacks (events) from the server,
I do create an event wrapper. I have posted in this newsgroup a sample
remoting soliution. Search for event wrapper.

>
> if not, then what do I need to do to get this to function....It
> shouldn't be "brain surgery"
> to do this, but it seems like it is...
>
> (3) How to set the configuration file to get additional information

See above.


Please, keep in mind that windows forms are NOT thread safe, and every
remoting call is executed on a different thread. So, you are going to
have big troubles if you hook server events directly to the form. Even
using a wrapper, in the wrapper class you have to check IsInvokeRequred
of the form, and to use form.Invoke if needed to pass the event to the
forms thread.

Read this article about threading with forms:

http://www.yoda.arachsys.com/csharp/multithreading.html#win...

Cheers
Sunny

Allen Anderson

7/21/2004 3:11:00 PM

0

your explanation is a bit hard to follow. It seems what your trying
to do is register the client for events. However, your doing that in
a very strange way. What you need to do is expose an event from the
remote object and have the client subscribe to that event. Then when
you want to fire the event you just call the event from your class
which can be trigged from your server calling the routine that fires
that event.

Cheers,
Allen Anderson
http://www.glacialcomp...
mailto: allen@put my website base here.com

On Tue, 20 Jul 2004 18:12:14 -0700, "Chester West"
<CWEST@Video-mation.com> wrote:

>Greetings Everyone -
>
>I'm trying to do the following:
>
> On one machine (let's call it the SERVER), I'm creating a object. Then
>I'm exposing it
> for remoting by executing a
>System.Runtime.Remoting.RemotingServices.Marshal call.
>
> On another machine (let's call it the CLIENT) I'm successfully getting a
>instantiation of the
> Remoting Object created on the SERVER. I can see the values of
>properties.
>
> Then, since the CLIENT is a C# application form, I attempt to establish
>a reference within the
> object so that I can perform processing (I.E., at the SERVER, I set
>processing
> parameters and a flag which in theory will cause an event to fire,
>alerting the CLIENT
> that processing needs to occur) by doing the following:
>
> this.ServerAgent.SetFormReference(this)
>
> where "this" is a reference to the CLIENT form. The "ServerAgent" is the
>remoting object
> created on the server. The "ServerAgent" then simply stores the
>reference so that it can
> perform processing.
>
> Unfortunately, As soon as I attempt to execute the
>"this.ServerAgent.SetFormReference(this)"
> I get an exception. Something REALLY informative, like "the server has
>caused an exception.
> For more details turn on the ConfigErrors section in the configuration
>file".
>
> Of course, this is a C# application so I have no idea how to turn on the
>items required to get the
> details, since the ConfigErrors setting seems to refer to ASP.NET.
>
> I suspect that since the form is running on the CLIENT that .NET cannot
>resolve the call since it
> is not running in the same process or something like that.
>
> My questions are:
> (1) Am I right in the assumption above?
>
> (2) Do I need to create 2 remoting objects (1 on the SERVER, 1 on the
>CLIENT) to
> accomplish the ability for the server to tell the client to execute
>commands.
>
> if not, then what do I need to do to get this to function....It
>shouldn't be "brain surgery"
> to do this, but it seems like it is...
>
> (3) How to set the configuration file to get additional information
>
>Thanks
>

Chester West

7/21/2004 10:14:00 PM

0

Sunny -

First, as always thanks for the assist....

I'm still having trouble though....I've reviewed your code and don't quite
understand why your not hooking directly up to the delegate on the client
side.

When I attempt to do the same thing to keep a reference, I get an exception
(again one of those fabulous Microsoft exceptions telling you absolutely
nothing!).

I figure I need 4 events for my remoting object. On the server side, I have
the following:

An event to indicate that the remote connection has been established
An event to signal that completion of a operation has occurred.

On the client side, I have the following:
An event to signal when a command needs to be processed.
An event to display a message to the client


The code that I'm using to hook up on the client side follows, as well as
the object.

Can you please tell me what I'm missing ???????????????????????
//Create the object for recieving .NET remoting messages from the Agent

int MyPort=this.MainMenu.PortOfAgent;

string Port=MyPort.ToString();

string url = "tcp://"+this.ConnectedAgentIP+":"+Port+"/VMRemoteControl" ;

RemotingConfiguration.RegisterWellKnownClientType ( typeof (
VMRemoteControl ), url ) ;

TcpClientChannel channel = new TcpClientChannel( ) ;

ChannelServices.RegisterChannel ( channel ) ;

//Get a reference to the remoting object....

this.AgentMessenger=(IServer) Activator.GetObject(typeof(IServer),url);

this.AgentController=(LOVE4000.VMRemoteControl) this.AgentMessenger;

//

//Hook up the events....

//The events the client will handle are commands and MessageBox messages

//

ClientEventHandlerDelegate ProcessingNeededMethod=new
ClientEventHandlerDelegate(this.ProcessACommand);

ClientMessageHandlerDelegate DisplayMsgMethod=new
ClientMessageHandlerDelegate(this.DisplayServersMessage);

EventWrapper eventwrapper=new
EventWrapper(ProcessingNeededMethod,DisplayMsgMethod,null,null);

//Do NOT HOOK DIRECTLY, but hold a reference to the delegate

this.ProcessingHandler=new
ClientEventHandlerDelegate(eventwrapper.ProcessingNeededEventHandler);

this.AgentMessenger.ProcessingNeeded+=this.ProcessingHandler;

this.MessageBoxHandler=new
ClientMessageHandlerDelegate(eventwrapper.MsgProcessingHandler);

this.AgentMessenger.MessageProcessor+=this.MessageBoxHandler;

//Signal to the user that the connection has been completed....

this.AgentController.ClientConnectionMade=true;



***************************************************

The source of the remoting object is below:

using System;

using System.Runtime.Remoting;

using System.Runtime.Remoting.Channels;

using System.Runtime.Remoting.Channels.Tcp;



namespace LOVE4000

{

/// <summary>

/// The following class is meant to be used on the CLIENT side

/// for communicating requests from the AGENT machine to the

/// end-user machine for processing.

/// </summary>


public delegate void ClientEventHandlerDelegate();

public delegate void ClientMessageHandlerDelegate(string Msg);

public delegate void ClientConnectionDelegate(bool Status);

public interface IServer

{

//The events that the client should handle

event ClientEventHandlerDelegate ProcessingNeeded;

//Either the client or the server can handle this event

event ClientMessageHandlerDelegate MessageProcessor;

//The events that the server should handle

event ClientEventHandlerDelegate ProcessingCompleted;

event ClientConnectionDelegate ConnectionChange;

}



public class EventWrapper : MarshalByRefObject

{

private event ClientEventHandlerDelegate ProcessingNeeded;

private event ClientMessageHandlerDelegate MsgProcessor;

private event ClientEventHandlerDelegate HasCompleted;

private event ClientConnectionDelegate ChangeOnConnection;

public EventWrapper(ClientEventHandlerDelegate ProcessEventHandler,

ClientMessageHandlerDelegate MsgEventHandler,

ClientConnectionDelegate ConnectionChangeHandler,

ClientEventHandlerDelegate ProcessCompleteHandler)

{

if (ProcessEventHandler!=null)

this.ProcessingNeeded+=ProcessEventHandler;

else

throw new ArgumentNullException("ProcessEventHandler");

if (MsgEventHandler!=null)

this.MsgProcessor+=MsgEventHandler;

else

throw new ArgumentException("MsgEventHandler");

if (ProcessCompleteHandler!=null)

this.HasCompleted+=ProcessCompleteHandler;

if (ConnectionChangeHandler!=null)

this.ChangeOnConnection+=ConnectionChangeHandler;

}

public void ProcessingNeededEventHandler()

{

if (this.ProcessingNeeded!=null)

this.ProcessingNeeded();

}

public void MsgProcessingHandler(string Msg)

{

if (this.MsgProcessor!=null)

this.MsgProcessor(Msg);

}

public void ProcessingCompleted()

{

if (this.HasCompleted!=null)

this.HasCompleted();

}

public void ChangeInConnection(bool Status)

{

if (this.ChangeOnConnection!=null)

this.ChangeOnConnection(Status);

}

}

[Serializable]

public class VMRemoteControl:MarshalByRefObject,IServer

{

//Declare the event that will get the notification

//that processing is needed

public event ClientEventHandlerDelegate ProcessingNeeded;

public event ClientMessageHandlerDelegate MessageProcessor;

public event ClientEventHandlerDelegate ProcessingCompleted;

public event ClientConnectionDelegate ConnectionChange;

private bool ProcessingRequired=false;

private bool HasBeenProcessed=false;

private bool ConnectedToClient=false;

private string MsgToShow="";



public string CommandToProcess="";

public object Parm1=null;

//Class Instantiation Method

public VMRemoteControl()

{

}

//

//Property & methods to indicate that a connection to this

//object has been made. This will be used as a signal to

//the server that the remoting has been completed.

//

public bool ClientConnectionMade

{

get {return this.ConnectedToClient;}

set

{

this.ConnectedToClient=value;

this.ConnectionStatusChanged(this.ConnectedToClient);

}

}

private void ConnectionStatusChanged(bool Status)

{

if (this.ConnectionChange!=null)

this.ConnectionChange(Status);

}


//

//Property & methods to handle displaying messages

//on the client machine

//

public string Message

{

get {return this.MsgToShow;}

set

{

this.MsgToShow=value;

this.DisplayMessage(this.MsgToShow);

}

}

private void DisplayMessage(string Msg)

{

if (this.MessageProcessor!=null)

{

this.MessageProcessor(Msg);

this.MsgToShow="";

}

}

//

//Property & Methods to handle indication

//the processing was completed

//

public bool WasProcessed

{

get {return this.HasBeenProcessed;}

set

{

this.HasBeenProcessed=value;

if (this.HasBeenProcessed==true)

{

this.ProcessingRequired=false;

this.ProcessingFinished();

}

}

}

private void ProcessingFinished()

{

if (this.ProcessingCompleted!=null)

this.ProcessingCompleted();

}

//

//Property & methods to indicate to the client

//that a command needs to be processed

//

//The CommandToProcess, as well as the parameters

//should be set prior to processing

//

public bool ProcessIt

{

get {return this.ProcessingRequired;}

set

{

this.ProcessingRequired=value;

if (this.ProcessingRequired==true)

{

this.WasProcessed=false;

this.SendProcessingRequired();

}

}

}

private void SendProcessingRequired()

{

if (this.ProcessingNeeded!=null)

this.ProcessingNeeded();

else

throw new ArgumentNullException("ProcessingNeeded");

}

}

}




"Sunny" <sunny@newsgroups.nospam> wrote in message
news:e2aqgJzbEHA.2408@tk2msftngp13.phx.gbl...
> Hi Chester,
> read inline:
>
> In article <OPsVu#rbEHA.2388@TK2MSFTNGP11.phx.gbl>, CWEST@Video-
> mation.com says...
> >
> > this.ServerAgent.SetFormReference(this)
> >
> > where "this" is a reference to the CLIENT form. The "ServerAgent" is
the
> > remoting object
> > created on the server. The "ServerAgent" then simply stores the
> > reference so that it can
> > perform processing.
>
> This is bad idea. It is better to implement a simple wrapper class which
> you can use to transfer the calls from the server to the client.
>
> >
> > Unfortunately, As soon as I attempt to execute the
> > "this.ServerAgent.SetFormReference(this)"
> > I get an exception. Something REALLY informative, like "the server
has
> > caused an exception.
> > For more details turn on the ConfigErrors section in the
configuration
> > file".
>
> The exception you see is because server have to have access to the
> assembly of the client class, to which it is connected. In your
> situation - the form. Thats why I sugested a wrapper. You can put this
> wrapper class in a shared assembly and deploy it both with the client
> and the server.
>
> >
> > Of course, this is a C# application so I have no idea how to turn on
the
> > items required to get the
> > details, since the ConfigErrors setting seems to refer to ASP.NET.
>
> it is not ConfigErrors, but customErrors. Note it is case sensitive. You
> have to put it in a config file (customErrors = off). And read it from
> your server app with RemotingConfiguration.Configure.
>
> >
> > I suspect that since the form is running on the CLIENT that .NET
cannot
> > resolve the call since it
> > is not running in the same process or something like that.
>
> Not the process, just the server knows nothing about your client class
> (form). How do you expect to call something without knowing it?
>
> >
> > My questions are:
> > (1) Am I right in the assumption above?
>
> Partialy. I have filled the gaps :)
>
> >
> > (2) Do I need to create 2 remoting objects (1 on the SERVER, 1 on
the
> > CLIENT) to
> > accomplish the ability for the server to tell the client to
execute
> > commands.
>
> Yes, you have. Usualy, when I need a callbacks (events) from the server,
> I do create an event wrapper. I have posted in this newsgroup a sample
> remoting soliution. Search for event wrapper.
>
> >
> > if not, then what do I need to do to get this to function....It
> > shouldn't be "brain surgery"
> > to do this, but it seems like it is...
> >
> > (3) How to set the configuration file to get additional information
>
> See above.
>
>
> Please, keep in mind that windows forms are NOT thread safe, and every
> remoting call is executed on a different thread. So, you are going to
> have big troubles if you hook server events directly to the form. Even
> using a wrapper, in the wrapper class you have to check IsInvokeRequred
> of the form, and to use form.Invoke if needed to pass the event to the
> forms thread.
>
> Read this article about threading with forms:
>
> http://www.yoda.arachsys.com/csharp/multithreading.html#win...
>
> Cheers
> Sunny


Sunny

7/22/2004 4:25:00 AM

0

Hi Chester,
I had no time to review the code, but I'll try to answer to your questions
and to explain how the things work.

As a beginning lets review how remoting works without events.

So, you have a client, which needs some information, and a server which
prepares and sends that information. The client invokes remotely a method
in the server and the server responds. All this to work, the client have to
know what method to invoke, and in what type of object is this method, i.e.
the client needs a description of the remoted class. To provide the client
with that information, there are some options:
- copy the assembly which contains the server class to the client (bad).
- use soapsuds.exe to get only the metadata for that class, and use the
result in the client (if soapsuds was not so buggy and limited)
- use interfaces (like I do) or abstract classes (the approach is the same,
as interfaces) in a separate assembly, and use this assembly at the client
and at the server.

Now, what are the events. The events are pure method calls, but using a
delegates (or function pointers in c/c++ terms). The thelegate contains a
reference to a method in some object to be called. So, when the server
wants to rise an event, it actually just invokes a method in the client,
i.e. at this moment for this call the roles are switched (the server
becomes a client for that call, and the client becomes a server who serves
the call). Now you see that the server can not call a method on the client,
without knowing about the class in which this method is declared, exactly
as like the client needs to know about the server object. To have this, you
have some options :) :
- copy the client assembly to the server (sounds familiar? )
- ... maybe use soadsuds (never tried in that scenario, so I'm not sure)
- use shared assembly. (oh, we already have one because of the server
object :) )

And as addition, you need to have a server channel, opened at the client in
order to receive the event. So you do not use TcpClientChannel, but
TcpChannel (it creates 2 channels, a client and a server channel).

What I have in my example:

pure interface approach implementation. With one addition, I have added a
very simple event wrapper (or forwarder). This way the client does not need
to know anything about the server object, except that it implements that
shared interface. And the server does not need any info about the client
class in order to send events, because the server already knows about the
forwarder.

Now, continue inline:

Chester West wrote:

> I'm still having trouble though....I've reviewed your code and don't quite
> understand why your not hooking directly up to the delegate on the client
> side.

Because my server knows nothing about my client. If I hook directly, an
exception will be thrown.

>
> When I attempt to do the same thing to keep a reference, I get an
> exception (again one of those fabulous Microsoft exceptions telling you
> absolutely nothing!).

As above ... :)


for the next question, I need more info, like - who fires the event and who
is the receiver.

>
> I figure I need 4 events for my remoting object. On the server side, I
> have the following:
>
> An event to indicate that the remote connection has been established
> An event to signal that completion of a operation has occurred.
>
> On the client side, I have the following:
> An event to signal when a command needs to be processed.
> An event to display a message to the client


As final words, you have to have in mind this article as well (read, and
implement the second approach, it does not requre to buy the product), if
you are going to fire an event to a multiple clients.

http://www.genuinechannels.com/Content.aspx?id=27&...

Waw, it become like a novel ... :)

Cheers
Sunny

Chester West

7/22/2004 8:21:00 PM

0

Sunny -

Again, thanks for the assistance....I REALLY appreciate you taking a
"newbie" under your wing...

All of this makes sense. However, in regards to the client and server, in
the application I am working on there is only one application, which can be
either a client or a server depending on the situation. What is common is
that
it is (at this point) pier-to-pier. Later there will be more then one
server...but there will always be ONE master server while the other machines
will be considered as clients.

That being said, I'm wondering if it makes sense to create a wrapper for
the events since both the client and the server (in theory) know about the
events and because of the additional complexity involved.

As I indicated, when I'm trying to hook up after creating a wrapper to hold
the reference, I'm getting the exception. I can't see that I've done
anything wrong...the only difference (and perhaps, in error) I see is that I
am using the TcpClientChannel for connecting up on the Client-side form
while on the Server side form I'm using TcpChannel.

My plan at this point is to try the following:
(1) Try changing the TcpClientChannel on the client-side form to
TcpChannel..re-try, and if it fails proceed to step 2
(2) Try changing the TcpChannel on the server side form to TcpServerChannel,
leaving the TcpClientChannel alone...re-try and if it fails go to step 3
(3) Try change the TcpClientChannel to TcpChannel to match up with the
server-form...re-try it and if if fails go to step 4
(4) Re-implement the class, starting with your example....if it works build
incrementally until I have what I need...if not, go to step 5
(5) Look at using the TcpListener class to implement things...if I decide it
is not exactly what I want to use go to step 6
(6) Implement messaging by creating a table in SQL server, and poll the
table every second (not very scalable, but at least it will work...)

If you've got further idea's I'm listening....I'll look at the article
you've sent (you send very informative ones!)

Thanks

"Sunny" <sunny@newsgroups.nospam> wrote in message
news:%23PG%23UP6bEHA.644@tk2msftngp13.phx.gbl...
> Hi Chester,
> I had no time to review the code, but I'll try to answer to your questions
> and to explain how the things work.
>
> As a beginning lets review how remoting works without events.
>
> So, you have a client, which needs some information, and a server which
> prepares and sends that information. The client invokes remotely a method
> in the server and the server responds. All this to work, the client have
to
> know what method to invoke, and in what type of object is this method,
i.e.
> the client needs a description of the remoted class. To provide the client
> with that information, there are some options:
> - copy the assembly which contains the server class to the client (bad).
> - use soapsuds.exe to get only the metadata for that class, and use the
> result in the client (if soapsuds was not so buggy and limited)
> - use interfaces (like I do) or abstract classes (the approach is the
same,
> as interfaces) in a separate assembly, and use this assembly at the client
> and at the server.
>
> Now, what are the events. The events are pure method calls, but using a
> delegates (or function pointers in c/c++ terms). The thelegate contains a
> reference to a method in some object to be called. So, when the server
> wants to rise an event, it actually just invokes a method in the client,
> i.e. at this moment for this call the roles are switched (the server
> becomes a client for that call, and the client becomes a server who serves
> the call). Now you see that the server can not call a method on the
client,
> without knowing about the class in which this method is declared, exactly
> as like the client needs to know about the server object. To have this,
you
> have some options :) :
> - copy the client assembly to the server (sounds familiar? )
> - ... maybe use soadsuds (never tried in that scenario, so I'm not sure)
> - use shared assembly. (oh, we already have one because of the server
> object :) )
>
> And as addition, you need to have a server channel, opened at the client
in
> order to receive the event. So you do not use TcpClientChannel, but
> TcpChannel (it creates 2 channels, a client and a server channel).
>
> What I have in my example:
>
> pure interface approach implementation. With one addition, I have added a
> very simple event wrapper (or forwarder). This way the client does not
need
> to know anything about the server object, except that it implements that
> shared interface. And the server does not need any info about the client
> class in order to send events, because the server already knows about the
> forwarder.
>
> Now, continue inline:
>
> Chester West wrote:
>
> > I'm still having trouble though....I've reviewed your code and don't
quite
> > understand why your not hooking directly up to the delegate on the
client
> > side.
>
> Because my server knows nothing about my client. If I hook directly, an
> exception will be thrown.
>
> >
> > When I attempt to do the same thing to keep a reference, I get an
> > exception (again one of those fabulous Microsoft exceptions telling you
> > absolutely nothing!).
>
> As above ... :)
>
>
> for the next question, I need more info, like - who fires the event and
who
> is the receiver.
>
> >
> > I figure I need 4 events for my remoting object. On the server side, I
> > have the following:
> >
> > An event to indicate that the remote connection has been established
> > An event to signal that completion of a operation has occurred.
> >
> > On the client side, I have the following:
> > An event to signal when a command needs to be processed.
> > An event to display a message to the client
>
>
> As final words, you have to have in mind this article as well (read, and
> implement the second approach, it does not requre to buy the product), if
> you are going to fire an event to a multiple clients.
>
> http://www.genuinechannels.com/Content.aspx?id=27&...
>
> Waw, it become like a novel ... :)
>
> Cheers
> Sunny


Sunny

7/22/2004 9:42:00 PM

0

Hi Chester,
inline:

In article <e39kPlCcEHA.3012@tk2msftngp13.phx.gbl>, cwest@video-
mation.com says...
> Sunny -
>
> Again, thanks for the assistance....I REALLY appreciate you taking a
> "newbie" under your wing...
>
> All of this makes sense. However, in regards to the client and server, in
> the application I am working on there is only one application, which can be
> either a client or a server depending on the situation. What is common is
> that
> it is (at this point) pier-to-pier. Later there will be more then one
> server...but there will always be ONE master server while the other machines
> will be considered as clients.

If the application is only one and the same, there is no need of wrapper
indeed. Actually I do not know what deployment you will have, but if you
are going to release copies which will not be under your control, you
have to take in mind the possible complications with the upgrades.
Lets say you have version 1 of your app distributed. Now comes version
2, in which you have added a new functionality, some additional methods,
or you have corrected a bug. When you recompile the new version, the old
apps will not be able to communicate with the new one, because you have
changed the assembly in which your remoting class resided. Thats why I
always recommend the interface approach. Even if you change your
remoting class, it will still implement the shared interface, so the old
versions will still be able to connect.
Of course, it is not obligatory, I just make a point.

>
> That being said, I'm wondering if it makes sense to create a wrapper for
> the events since both the client and the server (in theory) know about the
> events and because of the additional complexity involved.

As I said, no need. I would only correct the wording here. The problem
is when the server does not know about the receiving object in the
client, to which the event is hooked. But as far as it is the same app,
the server will know about the client classes :)

>
> As I indicated, when I'm trying to hook up after creating a wrapper to hold
> the reference, I'm getting the exception. I can't see that I've done
> anything wrong...the only difference (and perhaps, in error) I see is that I
> am using the TcpClientChannel for connecting up on the Client-side form
> while on the Server side form I'm using TcpChannel.

In my prev post I told you that most probably the problem is that you
use TcpClientChannel. This channel does not open a listening port to
accept the server callbacks. TcpClient should solve this.

>
> My plan at this point is to try the following:
> (1) Try changing the TcpClientChannel on the client-side form to
> TcpChannel..re-try, and if it fails proceed to step 2

yes :)

> (2) Try changing the TcpChannel on the server side form to TcpServerChannel,
> leaving the TcpClientChannel alone...re-try and if it fails go to step 3

no need. TcpChannel opens Client and Server channels

> (3) Try change the TcpClientChannel to TcpChannel to match up with the
> server-form...re-try it and if if fails go to step 4

like 2.

> (4) Re-implement the class, starting with your example....if it works build
> incrementally until I have what I need...if not, go to step 5

Here you can prepare a more generic event wrapper, so you can use it for
different events.

> (5) Look at using the TcpListener class to implement things...if I decide it
> is not exactly what I want to use go to step 6

Hmmm, if it is not a pure data exchange, better stay with remoting :).
If you are going to open a new socket for every event ...

> (6) Implement messaging by creating a table in SQL server, and poll the
> table every second (not very scalable, but at least it will work...)

So, just replacing one type of server with another, more heavy :)

>
> If you've got further idea's I'm listening....I'll look at the article
> you've sent (you send very informative ones!)

whithout knowing the final goal ... no way :)


Cheers
Sunny