다음을 통해 공유


WCF Hello World, Part 2: Building a Server

Writing a server that directly uses the channel model is not much more difficult than writing a client application.  You'll need to grab a copy of yesterday's client application if you want someone that can to talk to your server.

Very few people are actually going to write a server application using the channel model.  This is what happens behind the scenes when you call new ServiceHost(typeof(MyWebService)) .

 using System;
using System.ServiceModel;
using System.ServiceModel.Channels;

class Server
{
   static void Main(string[] args)
   {
      TextMessageEncodingBindingElement encoder = new TextMessageEncodingBindingElement();
      TcpTransportBindingElement transport = new TcpTransportBindingElement();
      transport.TransferMode = TransferMode.Streamed;
      CustomBinding binding = new CustomBinding(encoder, transport);
      Uri address = new Uri("net.tcp://localhost:5555/");
      IChannelListener<IReplyChannel> listener = binding.BuildChannelListener<IReplyChannel>(address);
      listener.Open();
      while (listener.WaitForChannel(TimeSpan.FromMinutes(5)))
      {
         IReplyChannel channel = listener.AcceptChannel();
         channel.Open();
         IRequestContext context = channel.ReceiveRequest();
         Message request = context.RequestMessage;
         Console.Out.WriteLine(request.Headers.Action);
         if (request.Headers.Action == "hello")
         {
            Message reply = Message.CreateMessage(listener.MessageVersion, "wcf");
            context.Reply(reply);
         }
         request.Close();
         context.Close();
         channel.Close();
      }
      listener.Close();
   }
}

The client and server have to use compatible binding so we don't have a lot of choice there.  The procedure for the rest of the server is that we

  1. create a channel listener from the binding,
  2. start listening at a particular address,
  3. grab the connection when a client contacts us,
  4. read a message from the client,
  5. and send a response if the message matches what we were expecting.

Now, let's look at what gets sent over the wire when we have both the client and server in place.

 IP 192.168.0.3.3756 > 192.168.0.2.5555: tcp 0
  0x0000:  4500 0030 2215 4000 8006 575d c0a8 0003  E..0".@...W]....
  0x0010:  c0a8 0002 0eac 15b3 7ee6 0cbe 0000 0000  ........~.......
  0x0020:  7002 ffff 51c6 0000 0204 05b4 0101 0402  p...Q...........
IP 192.168.0.2.5555 > 192.168.0.3.3756: tcp 0
  0x0000:  4500 0030 347c 4000 8006 44f6 c0a8 0002  E..04|@...D.....
  0x0010:  c0a8 0003 15b3 0eac 02ec 2eb3 7ee6 0cbf  ............~...
  0x0020:  7012 ffff 2016 0000 0204 05b4 0101 0402  p...............

We have life on both sides of the connection!  From now on, I'm going to just call out the segments with content and skip the rest of the TCP traffic that makes up a conversation.

 IP 192.168.0.3.3756 > 192.168.0.2.5555: tcp 37
  0x0000:  4500 004d 2217 4000 8006 573e c0a8 0003  E..M".@...W>....
   0x0010:  c0a8 0002 0eac 15b3 7ee6 0cbf 02ec 2eb4  ........~.......
  0x0020:  5018 ffff 21e7 0000 0001 0001 0102 1b6e  P...!..........n
  0x0030:  6574 2e74 6370 3a2f 2f31 3932 2e31 3638  et.tcp://192.168
  0x0040:  2e30 2e32 3a35 3535 352f 0303 0c         .0.2:5555/...
IP 192.168.0.3.3756 > 192.168.0.2.5555: tcp 260
   0x0000:  4500 012c 221a 4000 8006 565c c0a8 0003  E..,".@...V\....
  0x0010:  c0a8 0002 0eac 15b3 7ee6 0ce5 02ec 2eb5  ........~.......
  0x0020:  5018 fffe f365 0000 3c73 3a45 6e76 656c  P....e..<s:Envel
   0x0030:  6f70 6520 786d 6c6e 733a 733d 2268 7474  ope.xmlns:s="htt
  0x0040:  703a 2f2f 7777 772e 7733 2e6f 7267 2f32  p://www.w3.org/2
  0x0050:  3030 332f 3035 2f73 6f61 702d 656e 7665  003/05/soap-enve
  0x0060:  6c6f 7065 2220 786d 6c6e 733a 613d 2268  lope".xmlns:a="h
  0x0070:  7474 703a 2f2f 7777 772e 7733 2e6f 7267  ttp://www.w3.org
  0x0080:  2f32 3030 352f 3038 2f61 6464 7265 7373  /2005/08/address
  0x0090:  696e 6722 3e3c 733a 4865 6164 6572 3e3c  ing"><s:Header><
  0x00a0:  613a 4163 7469 6f6e 2073 3a6d 7573 7455  a:Action.s:mustU
  0x00b0:  6e64 6572 7374 616e 643d 2231 223e 6865  nderstand="1">he
   0x00c0:  6c6c 6f3c 2f61 3a41 6374 696f 6e3e 3c61  llo</a:Action><a
 0x00d0:  3a54 6f20 733a 6d75 7374 556e 6465 7273  :To.s:mustUnders
  0x00e0:  7461 6e64 3d22 3122 3e6e 6574 2e74 6370  tand="1">net.tcp
   0x00f0:  3a2f 2f31 3932 2e31 3638 2e30 2e32 3a35  ://192.168.0.2:5
  0x0100:  3535 352f 3c2f 613a 546f 3e3c 2f73 3a48  555/</a:To></s:H
 0x0110:  6561 6465 723e 3c73 3a42 6f64 792f 3e3c  eader><s:Body/><
  0x0120:  2f73 3a45 6e76 656c 6f70 653e            /s:Envelope>
IP 192.168.0.2.5555 > 192.168.0.3.3756: tcp 197
 0x0000:  4500 00ed 3481 4000 8006 4434 c0a8 0002  E...4.@...D4....
  0x0010:  c0a8 0003 15b3 0eac 02ec 2eb6 7ee6 0dea  ............~...
  0x0020:  5018 fed5 8235 0000 3c73 3a45 6e76 656c  P....5..<s:Envel
   0x0030:  6f70 6520 786d 6c6e 733a 733d 2268 7474  ope.xmlns:s="htt
  0x0040:  703a 2f2f 7777 772e 7733 2e6f 7267 2f32  p://www.w3.org/2
  0x0050:  3030 332f 3035 2f73 6f61 702d 656e 7665  003/05/soap-enve
  0x0060:  6c6f 7065 2220 786d 6c6e 733a 613d 2268  lope".xmlns:a="h
  0x0070:  7474 703a 2f2f 7777 772e 7733 2e6f 7267  ttp://www.w3.org
  0x0080:  2f32 3030 352f 3038 2f61 6464 7265 7373  /2005/08/address
  0x0090:  696e 6722 3e3c 733a 4865 6164 6572 3e3c  ing"><s:Header><
  0x00a0:  613a 4163 7469 6f6e 2073 3a6d 7573 7455  a:Action.s:mustU
  0x00b0:  6e64 6572 7374 616e 643d 2231 223e 7763  nderstand="1">wc
   0x00c0:  663c 2f61 3a41 6374 696f 6e3e 3c2f 733a  f</a:Action></s:
 0x00d0:  4865 6164 6572 3e3c 733a 426f 6479 2f3e  Header><s:Body/>
 0x00e0:  3c2f 733a 456e 7665 6c6f 7065 3e         </s:Envelope>

You can learn a lot by looking at what happens under the covers.  The first segment you see contains our destination address.  Then, you can see the SOAP message that the client sends.  Finally, you can see the SOAP message that the server responds with.  What if you don't want people to be able to look at your messages like this?  That's the subject for tomorrow's conclusion to the series.

Next time: WCF Hello World, Part 3: Enabling Security

Comments

  • Anonymous
    March 29, 2006
    During the past month, we've taken a tour of the most important parts of the channel model.&amp;nbsp; We...
  • Anonymous
    March 31, 2006
    Over the last two days we've looked at building a simple client and server that directly use the channel...
  • Anonymous
    April 19, 2006
    For the server, I took the example code I posted a few weeks ago and started making modifications. I've...
  • Anonymous
    October 17, 2006
    Over the last two days we've looked at building a simple client and server that directly use the channel