For the server, I took the example code I posted a few weeks ago and started making modifications. I've replaced the binding with a new one for the File Transport (we'll cover that code later this week) and added some reasonable timeouts for all of the operations. I also added some debug messages for tracing if you want to play with this once the series is over and experiment.
The action of the server is a very simple one for demonstration. The server will take a message with action equal to "http://reflect" and reverse the contents of the message body. This reply gets sent back in a message with action equal to "http://reflection". Why http in the action? Just to show that actions are simply a description of how the message should be processed and don't have any inherent meaning until you give them one.
using System; using System.ServiceModel.Channels; using FileTransport; namespace FileReplyChannelServer { class FileReplyChannelServer { static void Main(string[] args) { Console.Write("Creating listener..."); Binding binding = new FileTransportBinding(); Uri uri = new Uri("my.file://localhost/x"); IChannelListener<IReplyChannel> listener = binding.BuildChannelListener<IReplyChannel>(uri, new BindingParameterCollection()); listener.Open(TimeSpan.FromSeconds(5)); Console.WriteLine(" done."); Console.Write("Creating channel..."); IReplyChannel channel = listener.AcceptChannel(TimeSpan.FromSeconds(5)); channel.Open(TimeSpan.FromSeconds(5)); Console.WriteLine(" done."); Console.Write("Waiting for request..."); while (channel.WaitForRequest(TimeSpan.FromMinutes(1))) { using (IRequestContext context = channel.ReceiveRequest(TimeSpan.FromSeconds(5))) { Console.WriteLine(" done."); using (Message message = context.RequestMessage) { Console.WriteLine("Processing request: {0}", message.Headers.Action); if (message.Headers.Action == "http://reflect") { string response = ProcessReflectRequest(message.GetBody<string>()); Console.Write("Sending reply..."); Message replyMessage = Message.CreateMessage(MessageVersion.Default, "http://reflection", response); context.Reply(replyMessage, TimeSpan.FromSeconds(5)); Console.WriteLine(" done."); } } } Console.Write("Waiting for request..."); } Console.WriteLine(" terminated."); channel.Close(TimeSpan.FromSeconds(5)); } static string ProcessReflectRequest(string request) { char[] output = new char[request.Length]; for (int index = 0; index < request.Length; index++) { output[index] = request[request.Length - index - 1]; } return new string(output); } } }
This code works with the recent February CTP bits. If you don't have a WCF project template set up, you'll need to add references to the System.ServiceModel and System.Runtime.Serialization dlls. In Visual Studio, use Add Reference on the project to do this.
Next time: Building a Custom File Transport, Part 3: Client