This is the 3rd step - Simple Duplex
Ok..so why duplex?! in the final step I want to have a proxy that dynamically changes between online & offline state - in previous step we looked at MSMQ - that would be our "offline" solution...I need an "online" solution that will work implementing the same interface, which is "one-way", but I also want to benefit from the "online" state and actually receive "answers" from the server...
So...let's implement a simple Duplex on WCF - to do just that.
We'll start with the contract, since Duplex is designed for async processing, it is built from two "one-way" interfaces, the second acts as the callback interface.
We'll use the same contract as previous samples, we'll see the second -
ISampleContractCallback is registered as the "CallbackContract" of the first interface:
[ServiceContract(CallbackContract=typeof(ISampleContractCallback))]
public interface ISampleContract
{
[OperationContract(IsOneWay=true)]
void GetData(Guid identifier);
[OperationContract(IsOneWay = true)]
void Execute(Guid identifier);
}
public interface ISampleContractCallback
{
[OperationContract(IsOneWay = true)]
void SendData(Guid identifier, string answer);
}
Next we'll implement this interface on server side - our "business logic", here we'll call back the client with the "answer":
public class testFancyProxyService:ISampleContract
{
public void GetData(Guid identifier)
{
Console.WriteLine("recieved GetData request (id {0})", identifier);
ISampleContractCallback client = OperationContext.Current.GetCallbackChannel();
//get data by identifier
string answer = "hi! from the server";
client.SendData(identifier, answer);
}
public void Execute(Guid identifier)
{
Console.WriteLine("recieved Execute request (id {0})", identifier);
}
}
As previous samples, the host does not change:
class Program
{
private static ServiceHost serviceHost = null;
static void Main(string[] args)
{
try
{
startListening();
Console.WriteLine("Server is up, press any key to stop it...");
Console.Read();
}
catch (Exception ex)
{
Console.WriteLine(string.Format("Error: {0}\n\n Stack:{1}", ex.Message, ex.StackTrace));
Console.Read();
}
finally
{
stopListening();
}
}
private static void startListening()
{
// Create a ServiceHost for the CalculatorService type and
// provide the base address.
serviceHost = new ServiceHost(typeof(testFancyProxyServer.testFancyProxyService));
// Open the ServiceHostBase to create listeners and start
// listening for messages.
serviceHost.Open();
}
private static void stopListening()
{
if (serviceHost != null)
{
if (serviceHost.State == CommunicationState.Opened)
{
serviceHost.Close();
}
}
}
}
The server's endpoint stays as the "regular" TCP sample
<endpoint address="net.tcp://localhost:8080/testFancyProxy" binding="netTcpBinding"
bindingConfiguration=""
contract="testFancyProxyContracts.ISampleContract" />
Same thing on client side - we'll code a small proxy - here we'll create a 'DuplexChannelFactory' instead of a "regular" ChannelFactory:
public class testFancyProxyProxy:ISampleContract
{
InstanceContext m_context;
private NetTcpBinding tcpBinding;
private EndpointAddress endPointAddress;
ISampleContract proxy;
public testFancyProxyProxy(InstanceContext context)
{
m_context = context;
tcpBinding = new NetTcpBinding(SecurityMode.Transport);
endPointAddress = new EndpointAddress(ConfigurationSettings.AppSettings["ServerURI"]);
proxy = new DuplexChannelFactory(m_context, tcpBinding).CreateChannel(endPointAddress);
}
public void GetData(Guid identifier)
{
proxy.GetData(identifier);
}
public void Execute(Guid identifier)
{
proxy.Execute(identifier);
}
}
Testing...to receive an answer from server, we'll add implementation for ISampleContractCallback.
public class testFancyProxyConsumer : ISampleContractCallback
{
private static InstanceContext m_context = null;
private testFancyProxyClient.testFancyProxyProxy proxy;
public void Run()
{
m_context = new InstanceContext(this);
proxy = new testFancyProxyProxy(m_context);
proxy.GetData(Guid.NewGuid());
proxy.Execute(Guid.NewGuid());
}
//ISampleContractCallback:
public void SendData(Guid identifier, string answer)
{
Console.WriteLine("answer from server for id {0}: {1}", identifier, answer);
}
}
That's it!! 3rd step - that's it for the basics, till now we saw simple TCP, simple MSMQ and simple Duplex...next step we'll start with the more advanced steps towards our final goal - a duplex-dynamic proxy.
Till next step...
Diego
PS: source download
No comments:
Post a Comment