Server hangs on a client callback

D

dvestal

I'm new to .NET remoting, and I'm having trouble getting a callback to
work from a server. I've been through a dozen webpages and the
references available to me, but I'm still missing something.

I'm trying to have a client pass a callback function to a server, and
the server call it. The callback signature is determined by public
interfaces referenced by both client and server. I've worked through
about three problems on my own, but now I'm stuck.

A supersimplified example of my code is below. What happens is that
the client can subscribe, but when the server attempts to call the
HandleMessage method on the client, the method is never invoked. The
server appears to hang just before invoking the method. What am I
doing wrong?

SHARED LIBRARY
public interface ISubscriber {
void HandleMessage();
}
public interface IMessager {
Subscribe(ISubscriber subscriber);
}

SERVER
public class MessagerImp : IMessager
{
ISubscriber m_subscriber;

public MessagerImp()
{
m_subscriber = null;

BinaryServerFormatterSinkProvider provider
= new BinaryServerFormatterSinkProvider();
provider.TypeFilterLevel = TypeFilterLevel.Full;
TcpServerChannel channel = new TcpServerChannel
(
"TCP server channel with a binary formatter",
MessageClient.MessagerPort,
provider
);
ChannelServices.RegisterChannel(channel, true);

RemotingConfiguration.RegisterWellKnownServiceType
(
typeof(MessagerImp),
"tcp://MYMACHINE:1545/Messager.rpc",
WellKnownObjectMode.SingleCall
);

m_worker = new Thread(new ThreadStart(WorkerThreadMethod));
m_worker.Start();
}

public void Subscribe(ISubscriber subscriber) {
m_subscriber = subscriber;
}

public void WorkerThreadMethod()
{
while(true)
{
// This method hangs if it tries to invoke HandleMessage.
if(m_subscriber != null) m_subscriber.HandleMessage();
}
}
}

CLIENT
public class MessagerClient : ISubscriber
{
public MessagerClient()
{
ChannelServices.RegisterChannel(new TcpChannel(0), true);
IMessager rpcSvc = (IMessager)
Activator.GetObject(typeof(IMessager),
"tcp://MYMACHINE:1545/Messager.rpc");
rpcSvc.Subscribe(this);
}

public void HandleMessage()
{
// Method is never invoked.
}
}
 
D

Doug Forster

Well your MessagerClient class needs to be derived from MarshalByRefObject
to start with. Then you need to do some study of lifetime issues to deal
with your next set of problems.

Cheers
Doug Forster
 
D

dvestal

Doug said:
Well your MessagerClient class needs to be derived from MarshalByRefObject
to start with. Then you need to do some study of lifetime issues to deal
with your next set of problems.

Cheers
Doug Forster

Thanks, Doug.

The client now derives from MarshalByRefObject, and the server is now
exposed as a Singleton that overrides InitializeLifetimeService to
return null.

The server still hangs when it tries to call the callback. Would this
behavior occur if the client weren't listening on the appropriate port?
To receive callbacks, does the client need to expose itself as a
server, complete with RegisterWellKnownServiceType and all that?

Also, a related question. My server is inside a Windows service, and
it needs a thread running inside it that processes things. I'm having
trouble deciding whether the remoted object (MessagerImp) should just
pass things to a non-remoted, stateful object to do this work, or
whether there's a good way of keeping state and running threads inside
a remoted class. Any tips?
 

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