Folks, I have gathered all of the information required to get my WCF
client-server app working with client callbacks. The code in the two samples
I looked at are generally correct for guidance. The Chat
<http://www.codeproject.com/Articles/19752/WCF-WPF-Chat-Application>  app
that Wallace mentioned is dense reading and contains more than just a WCF
lesson. This WcfTicketingService <http://www.devx.com/dotnet/Article/38814>
demo is short and easier to read, but he only uses [OneWay] methods and
reckons this is a restriction when you a using callbacks.

 

I was upset to think that many of my service calls would be one way, as a
typical business method would update a DB row, get back a count, then
broadcast to clients that the DB had changed. I verified that you can't make
a callback in a non-OneWay method body because it will stall and timeout.
The answer is to do the work, trigger the callback loop on a different
thread then return your result. I created a long-lived Thread that is told
to wake up and lazily pull callback requests from a queue and send them. I'm
happy with this low-tech technique.

 

You will have overcome the security problems I mentioned yesterday. I
gave-up and set bind.Security.Mode to None on both sides.

 

My client makes a Login call to authenticate and I return a "ticket" that
must be passed to all service calls. I was wondering how to pass this ticket
in a side-band of all calls. I thought I'd have to suffer through writing
custom behaviours like I suspected a couple of years ago in my Silverlight
app. Back then I found that SL-WCF did not support the required behaviours
anyway and I had to pass data in message headers. I found that the same
technique works in my desktop app and I've used it. Create your service
proxy, create an OperationContextScope over its channel and add data like
this:

 

OperationContext.Current.OutgoingMessageHeaders.Add(MessageHeader.CreateHead
er("Ticket", "Namespace", ticket));

 

On the server side you can get the data like this:

 

int index =
OperationContext.Current.IncomingMessageHeaders.FindHeader("Ticket",
"Namespace");

var ticket =
OperationContext.Current.IncomingMessageHeaders.GetHeader<LoginTicket>(index
);

 

You have to take care to deal with errors from the service and the proxy
going to a Faulted state. So after overcoming all of the hurdles I am now
happy that WCF can replace all of the functionality I had for many years
with Remoting.

 

Greg

Reply via email to