Remoting->Delegate

N

Nadav

Hi,

I Wonder... Can a server-side class exposed through remoting expose a
delegate? In other words: can a client set a server-side delegate that
in-turn will be asynchronously called from the server on the client?

Thanks,
Nadav.
 
B

Bart Jacobs

Yes, that is possible. But there are two caveats:

1. A server can only call back to a client if the client has registered
a remoting channel. Callbacks are transported over a separate TCP
connection, which might be problematic in the presence of firewalls.

You can avoid using callbacks by having the client actively query for
events. It is a less convenient programming style, however.

2. Delegates are marshalled by value. This means that the delegate's
target object reference and its method info object are sent over the
wire. This implies that the receiver must have the metadata for the
target object.

This is probably not what you want. A cleaner solution is to use
interfaces. For example, instead of

delegate void MyEventHandler(int x);

use the following interface

interface IMyInterface {
void MyEvent(int x);
}

This way, the object is marshalled by reference and only the metadata
for the interface needs to be shared between the client and the server.

Consider the following server interface:

public delegate void NewMessageHandler(int messageId);
public delegate void MailboxFullHandler();

public interface IMailServer {
string GetMessageBody(int messageId);
event NewMessageHandler NewMessage;
event MailboxFullHandler MailboxFull;
}

This design suffers from the disadvantages associated with delegates as
discussed above. It also requires a separate connection from the server
to the client.

A design that avoids delegates, but that still requires a client channel
looks like this:

public interface IMailEventSink {
void NewMessage(int messageId);
void MailboxFull();
}

public interface IMailServer {
string GetMessageBody(int messageId);
void SetMailEventSink(IMailEventSink sink);
}

A design which avoids a client channel looks like this:

[Serializable]
public class MailEvent {
}

public class NewMessageEvent : MailEvent {
public int messageId;
}

public class MailboxFullEvent : MailEvent {
}

public interface IMailServer {
string GetMessageBody(int messageId);
MailEvent GetEvent();
}

The GetEvent method blocks until an event is available.

Happy coding!

Bart Jacobs
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top