Building a Custom File Transport, Part 2: Server


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

Comments (4)

  1. During the last few weeks I’ve been going over various parts of the channel model and giving some commentary…

  2. I once again used the trick of taking the code from the previous example for the client. The File Transport…

  3. We’ve passed the midway point for the custom file transport example.  Now that we’ve got the underlying…

  4. Today’s article is just a summary of what we’ve put together with the file transport and a demonstration…