Client subscribes to service and service calls clients back and that is what this is about.
1) A normal WCF contract for server(impementation) and client(for proxy)
[ServiceContract]
interface IMessage
{
[OperationContract]
void AddMessage(string message);
}
2) A special interface(not a contract) for server(proxy) and client(implementation)1) A normal WCF contract for server(impementation) and client(for proxy)
[ServiceContract]
interface IMessage
{
[OperationContract]
void AddMessage(string message);
}
interface IMessageCallback
{
[OperationContract(IsOneWay = true)]
void OnMessageAdded(string message, DateTime timestamp);
}
3) Add subscribe mechanism to normal WCF contract (given in step 1)
[ServiceContract(CallbackContract = typeof(IMessageCallback))]
public interface IMessage {
[OperationContract]
void AddMessage(string message);
[OperationContract]
bool Subscribe();
[OperationContract]
bool Unsubscribe(); }
4) Implentation of normal contract given in step 3
a) a list to store subscribers
private static readonly List<IMessageCallback> subscribers = new List<IMessageCallback>();
b) get subscriber(callback channel to client)
IMessageCallback callback = OperationContext.Current.GetCallbackChannel<IMessageCallback>();
c) add subscriber to list
subscribers.Add(callback);
complete code:
public bool Subscribe()
{
try {
IMessageCallback callback = OperationContext.Current.GetCallbackChannel<IMessageCallback>();
if (!subscribers.Contains(callback))
subscribers.Add(callback);
return true;
}
catch {
return false;
}
}
public bool Unsubscribe()
{
try {
IMessageCallback callback = OperationContext.Current.GetCallbackChannel<IMessageCallback>();
if (subscribers.Contains(callback))
subscribers.Remove(callback);
return true;
}
catch {
return false;
}
}
public void AddMessage(string message)
{
subscribers.ForEach(delegate(IMessageCallback callback)
{
if (((ICommunicationObject)callback).State == CommunicationState.Opened)
{
callback.OnMessageAdded(message, DateTime.Now); }
else {
subscribers.Remove(callback);
}
});
}
5) add a suitable binding in config
<endpoint address ="" binding="wsDualHttpBinding" contract="WCFCallbacks.IMessage">
6) Client implementation
a) implement call back contract(given in step 2)
b) dispose mechanism needed
c) a context is required
[CallbackBehavior(ConcurrencyMode = ConcurrencyMode.Reentrant)]
class Sender : IMessageCallback, IDisposable
{
private MessageClient messageClient; public void Go()
{
InstanceContext context = new InstanceContext(this);
messageClient = new MessageClient(context, "WSDualHttpBinding_IMessage");
for (int i = 0; i < 5; i++)
{
string message = string.Format("message #{0}", i);
Console.WriteLine(">>> Sending "+message);
messageClient.AddMessage(message);
}
}
public void OnMessageAdded(string message, DateTime timestamp)
{
Console.WriteLine("<<< Recieved {0} with a timestamp of {1}", message, timestamp);
}
public void Dispose()
{
messageClient.Unsubscribe();
messageClient.Close();
}
}
Courtesy
No comments:
Post a Comment