Today is the last part of the stream upgrade sample. We've already looked at all the parts required to make the stream upgrade operate: stream, binding element, provider, initiator, and acceptor. All that's left today is to build a test harness for the code and run it. Here are the previous parts of this series for reference. It's taken a little longer than I expected to get this out due to some server difficulties.
I've created a simple service with one operation for demonstration purposes.
using System;using System.ServiceModel;using System.ServiceModel.Channels;using System.ServiceModel.Description;namespace Microsoft.ServiceModel.Samples{ [ServiceContract] interface ICalculator { [OperationContract] int Add(int x, int y); } class CalculatorService : ICalculator { public int Add(int x, int y) { return x + y; } } class service { static void Main(string[] args) { Binding binding = new CustomBinding( new ROT128StreamUpgradeBindingElement(), new TextMessageEncodingBindingElement(), new TcpTransportBindingElement() ); ServiceHost host = new ServiceHost(typeof(CalculatorService), new Uri("net.tcp://localhost/")); host.AddServiceEndpoint(typeof(ICalculator), binding, ""); ServiceMetadataBehavior mexBehavior = new ServiceMetadataBehavior(); host.Description.Behaviors.Add(mexBehavior); Binding mexBinding = MetadataExchangeBindings.CreateMexTcpBinding(); host.AddServiceEndpoint(typeof(IMetadataExchange), mexBinding, "mex"); host.Open(); Console.WriteLine("Press <ENTER> to quit."); Console.ReadLine(); host.Close(); } }}
I've enabled metadata so you can generate the client proxy yourself using svcutil. The attachments to this post contain one such proxy. The client just connects to the service, makes one operation call, and then closes the connection.
using System;using System.ServiceModel;using System.ServiceModel.Channels;namespace Microsoft.ServiceModel.Samples{ class client { static void Main(string[] args) { Binding binding = new CustomBinding( new ROT128StreamUpgradeBindingElement(), new TextMessageEncodingBindingElement(), new TcpTransportBindingElement() ); CalculatorClient client = new CalculatorClient(binding, new EndpointAddress("net.tcp://localhost/")); client.Open(); if (client.Add(1, 2) != 3) { throw new Exception("Operation call failed!"); } client.Close(); } }}
Let's start by looking at what happens on the client side. Remember that the debug output is at the start of the Read or Write method of the stream. That means that when writing, we see the stream before rotation. When reading, we see the stream after one rotation. You can directly match up the reads and writes between the two sides.
[WRITE] 1 bytes 0C .[READ] 1 bytes 8B .[WRITE] 512 bytes 06 FD 03 3C 73 3A 45 6E 76 65 6C 6F 70 65 20 ...<s:Envelope 78 6D 6C 6E 73 3A 73 3D 22 68 74 74 70 3A 2F xmlns:s="http:/ 2F 77 77 77 2E 77 33 2E 6F 72 67 2F 32 30 30 /www.w3.org/200 33 2F 30 35 2F 73 6F 61 70 2D 65 6E 76 65 6C 3/05/soap-envel 6F 70 65 22 20 78 6D 6C 6E 73 3A 61 3D 22 68 ope" xmlns:a="h 74 74 70 3A 2F 2F 77 77 77 2E 77 33 2E 6F 72 ttp://www.w3.or 67 2F 32 30 30 35 2F 30 38 2F 61 64 64 72 65 g/2005/08/addre 73 73 69 6E 67 22 3E 3C 73 3A 48 65 61 64 65 ssing"><s:Heade 72 3E 3C 61 3A 41 63 74 69 6F 6E 20 73 3A 6D r><a:Action s:m 75 73 74 55 6E 64 65 72 73 74 61 6E 64 3D 22 ustUnderstand=" 31 22 3E 68 74 74 70 3A 2F 2F 74 65 6D 70 75 1">http://tempu 72 69 2E 6F 72 67 2F 49 43 61 6C 63 75 6C 61 ri.org/ICalcula 74 6F 72 2F 41 64 64 3C 2F 61 3A 41 63 74 69 tor/Add</a:Acti 6F 6E 3E 3C 61 3A 4D 65 73 73 61 67 65 49 44 on><a:MessageID 3E 75 72 6E 3A 75 75 69 64 3A 35 39 66 63 39 >urn:uuid:59fc9 66 63 39 2D 65 33 65 32 2D 34 62 63 31 2D 62 fc9-e3e2-4bc1-b 36 33 32 2D 34 61 33 38 39 39 30 32 34 61 62 632-4a3899024ab 39 3C 2F 61 3A 4D 65 73 73 61 67 65 49 44 3E 9</a:MessageID> 3C 61 3A 52 65 70 6C 79 54 6F 3E 3C 61 3A 41 <a:ReplyTo><a:A 64 64 72 65 73 73 3E 68 74 74 70 3A 2F 2F 77 ddress>http://w 77 77 2E 77 33 2E 6F 72 67 2F 32 30 30 35 2F ww.w3.org/2005/ 30 38 2F 61 64 64 72 65 73 73 69 6E 67 2F 61 08/addressing/a 6E 6F 6E 79 6D 6F 75 73 3C 2F 61 3A 41 64 64 nonymous</a:Add 72 65 73 73 3E 3C 2F 61 3A 52 65 70 6C 79 54 ress></a:ReplyT 6F 3E 3C 61 3A 54 6F 20 73 3A 6D 75 73 74 55 o><a:To s:mustU 6E 64 65 72 73 74 61 6E 64 3D 22 31 22 3E 6E nderstand="1">n 65 74 2E 74 63 70 3A 2F 2F 6C 6F 63 61 6C 68 et.tcp://localh 6F 73 74 2F 3C 2F 61 3A 54 6F 3E 3C 2F 73 3A ost/</a:To></s: 48 65 61 64 65 72 3E 3C 73 3A 42 6F 64 79 3E Header><s:Body> 3C 41 64 64 20 78 6D 6C 6E 73 3D 22 68 74 74 <Add xmlns="htt 70 3A 2F 2F 74 65 6D 70 75 72 69 2E 6F 72 67 p://tempuri.org 2F 22 3E 3C 78 3E 31 3C 2F 78 3E 3C 79 3E 32 /"><x>1</x><y>2 3C 2F 79 3E 3C 2F 41 64 64 3E 3C 2F 73 3A 42 </y></Add></s:B 6F 64 79 3E 3C 2F 73 3A 45 6E 76 65 6C 6F 70 ody></s:Envelop 65 3E e>[READ] 478 bytes 86 5B 83 BC F3 BA C5 EE F6 E5 EC EF F0 E5 A0 .[............. F8 ED EC EE F3 BA F3 BD A2 E8 F4 F4 F0 BA AF ............... AF F7 F7 F7 AE F7 B3 AE EF F2 E7 AF B2 B0 B0 ............... B3 AF B0 B5 AF F3 EF E1 F0 AD E5 EE F6 E5 EC ............... EF F0 E5 A2 A0 F8 ED EC EE F3 BA E1 BD A2 E8 ............... F4 F4 F0 BA AF AF F7 F7 F7 AE F7 B3 AE EF F2 ............... E7 AF B2 B0 B0 B5 AF B0 B8 AF E1 E4 E4 F2 E5 ............... F3 F3 E9 EE E7 A2 BE BC F3 BA C8 E5 E1 E4 E5 ............... F2 BE BC E1 BA C1 E3 F4 E9 EF EE A0 F3 BA ED ............... F5 F3 F4 D5 EE E4 E5 F2 F3 F4 E1 EE E4 BD A2 ............... B1 A2 BE E8 F4 F4 F0 BA AF AF F4 E5 ED F0 F5 ............... F2 E9 AE EF F2 E7 AF C9 C3 E1 EC E3 F5 EC E1 ............... F4 EF F2 AF C1 E4 E4 D2 E5 F3 F0 EF EE F3 E5 ............... BC AF E1 BA C1 E3 F4 E9 EF EE BE BC E1 BA D2 ............... E5 EC E1 F4 E5 F3 D4 EF BE F5 F2 EE BA F5 F5 ............... E9 E4 BA B5 B9 E6 E3 B9 E6 E3 B9 AD E5 B3 E5 ............... B2 AD B4 E2 E3 B1 AD E2 B6 B3 B2 AD B4 E1 B3 ............... B8 B9 B9 B0 B2 B4 E1 E2 B9 BC AF E1 BA D2 E5 ............... EC E1 F4 E5 F3 D4 EF BE BC E1 BA D4 EF A0 F3 ............... BA ED F5 F3 F4 D5 EE E4 E5 F2 F3 F4 E1 EE E4 ............... BD A2 B1 A2 BE E8 F4 F4 F0 BA AF AF F7 F7 F7 ............... AE F7 B3 AE EF F2 E7 AF B2 B0 B0 B5 AF B0 B8 ............... AF E1 E4 E4 F2 E5 F3 F3 E9 EE E7 AF E1 EE EF ............... EE F9 ED EF F5 F3 BC AF E1 BA D4 EF BE BC AF ............... F3 BA C8 E5 E1 E4 E5 F2 BE BC F3 BA C2 EF E4 ............... F9 BE BC C1 E4 E4 D2 E5 F3 F0 EF EE F3 E5 A0 ............... F8 ED EC EE F3 BD A2 E8 F4 F4 F0 BA AF AF F4 ............... E5 ED F0 F5 F2 E9 AE EF F2 E7 AF A2 BE BC C1 ............... E4 E4 D2 E5 F3 F5 EC F4 BE B3 BC AF C1 E4 E4 ............... D2 E5 F3 F5 EC F4 BE BC AF C1 E4 E4 D2 E5 F3 ............... F0 EF EE F3 E5 BE BC AF F3 BA C2 EF E4 F9 BE ............... BC AF F3 BA C5 EE F6 E5 EC EF F0 E5 BE .............[WRITE] 1 bytes 07 .[READ] 1 bytes 87 .
The start of each block is part of our framing format. You can clearly see the three sets of calls. The first set are single bytes for the end of connection establishment. The second set are the actual transfers for the service call. You can see the request on this side but the reply is obscured by the stream rotation as we have not yet undone the transformation. The third set are single bytes for connection termination.
Here's the same view showing what the server received and sent. Everything that was obscured on the client side is visible on the server side and vice versa.
Press <ENTER> to quit.[READ] 1 bytes 8C .[WRITE] 1 bytes 0B .[READ] 512 bytes 86 7D 83 BC F3 BA C5 EE F6 E5 EC EF F0 E5 A0 .}............. F8 ED EC EE F3 BA F3 BD A2 E8 F4 F4 F0 BA AF ............... AF F7 F7 F7 AE F7 B3 AE EF F2 E7 AF B2 B0 B0 ............... B3 AF B0 B5 AF F3 EF E1 F0 AD E5 EE F6 E5 EC ............... EF F0 E5 A2 A0 F8 ED EC EE F3 BA E1 BD A2 E8 ............... F4 F4 F0 BA AF AF F7 F7 F7 AE F7 B3 AE EF F2 ............... E7 AF B2 B0 B0 B5 AF B0 B8 AF E1 E4 E4 F2 E5 ............... F3 F3 E9 EE E7 A2 BE BC F3 BA C8 E5 E1 E4 E5 ............... F2 BE BC E1 BA C1 E3 F4 E9 EF EE A0 F3 BA ED ............... F5 F3 F4 D5 EE E4 E5 F2 F3 F4 E1 EE E4 BD A2 ............... B1 A2 BE E8 F4 F4 F0 BA AF AF F4 E5 ED F0 F5 ............... F2 E9 AE EF F2 E7 AF C9 C3 E1 EC E3 F5 EC E1 ............... F4 EF F2 AF C1 E4 E4 BC AF E1 BA C1 E3 F4 E9 ............... EF EE BE BC E1 BA CD E5 F3 F3 E1 E7 E5 C9 C4 ............... BE F5 F2 EE BA F5 F5 E9 E4 BA B5 B9 E6 E3 B9 ............... E6 E3 B9 AD E5 B3 E5 B2 AD B4 E2 E3 B1 AD E2 ............... B6 B3 B2 AD B4 E1 B3 B8 B9 B9 B0 B2 B4 E1 E2 ............... B9 BC AF E1 BA CD E5 F3 F3 E1 E7 E5 C9 C4 BE ............... BC E1 BA D2 E5 F0 EC F9 D4 EF BE BC E1 BA C1 ............... E4 E4 F2 E5 F3 F3 BE E8 F4 F4 F0 BA AF AF F7 ............... F7 F7 AE F7 B3 AE EF F2 E7 AF B2 B0 B0 B5 AF ............... B0 B8 AF E1 E4 E4 F2 E5 F3 F3 E9 EE E7 AF E1 ............... EE EF EE F9 ED EF F5 F3 BC AF E1 BA C1 E4 E4 ............... F2 E5 F3 F3 BE BC AF E1 BA D2 E5 F0 EC F9 D4 ............... EF BE BC E1 BA D4 EF A0 F3 BA ED F5 F3 F4 D5 ............... EE E4 E5 F2 F3 F4 E1 EE E4 BD A2 B1 A2 BE EE ............... E5 F4 AE F4 E3 F0 BA AF AF EC EF E3 E1 EC E8 ............... EF F3 F4 AF BC AF E1 BA D4 EF BE BC AF F3 BA ............... C8 E5 E1 E4 E5 F2 BE BC F3 BA C2 EF E4 F9 BE ............... BC C1 E4 E4 A0 F8 ED EC EE F3 BD A2 E8 F4 F4 ............... F0 BA AF AF F4 E5 ED F0 F5 F2 E9 AE EF F2 E7 ............... AF A2 BE BC F8 BE B1 BC AF F8 BE BC F9 BE B2 ............... BC AF F9 BE BC AF C1 E4 E4 BE BC AF F3 BA C2 ............... EF E4 F9 BE BC AF F3 BA C5 EE F6 E5 EC EF F0 ............... E5 BE ..[WRITE] 478 bytes 06 DB 03 3C 73 3A 45 6E 76 65 6C 6F 70 65 20 ...<s:Envelope 78 6D 6C 6E 73 3A 73 3D 22 68 74 74 70 3A 2F xmlns:s="http:/ 2F 77 77 77 2E 77 33 2E 6F 72 67 2F 32 30 30 /www.w3.org/200 33 2F 30 35 2F 73 6F 61 70 2D 65 6E 76 65 6C 3/05/soap-envel 6F 70 65 22 20 78 6D 6C 6E 73 3A 61 3D 22 68 ope" xmlns:a="h 74 74 70 3A 2F 2F 77 77 77 2E 77 33 2E 6F 72 ttp://www.w3.or 67 2F 32 30 30 35 2F 30 38 2F 61 64 64 72 65 g/2005/08/addre 73 73 69 6E 67 22 3E 3C 73 3A 48 65 61 64 65 ssing"><s:Heade 72 3E 3C 61 3A 41 63 74 69 6F 6E 20 73 3A 6D r><a:Action s:m 75 73 74 55 6E 64 65 72 73 74 61 6E 64 3D 22 ustUnderstand=" 31 22 3E 68 74 74 70 3A 2F 2F 74 65 6D 70 75 1">http://tempu 72 69 2E 6F 72 67 2F 49 43 61 6C 63 75 6C 61 ri.org/ICalcula 74 6F 72 2F 41 64 64 52 65 73 70 6F 6E 73 65 tor/AddResponse 3C 2F 61 3A 41 63 74 69 6F 6E 3E 3C 61 3A 52 </a:Action><a:R 65 6C 61 74 65 73 54 6F 3E 75 72 6E 3A 75 75 elatesTo>urn:uu 69 64 3A 35 39 66 63 39 66 63 39 2D 65 33 65 id:59fc9fc9-e3e 32 2D 34 62 63 31 2D 62 36 33 32 2D 34 61 33 2-4bc1-b632-4a3 38 39 39 30 32 34 61 62 39 3C 2F 61 3A 52 65 899024ab9</a:Re 6C 61 74 65 73 54 6F 3E 3C 61 3A 54 6F 20 73 latesTo><a:To s 3A 6D 75 73 74 55 6E 64 65 72 73 74 61 6E 64 :mustUnderstand 3D 22 31 22 3E 68 74 74 70 3A 2F 2F 77 77 77 ="1">http://www 2E 77 33 2E 6F 72 67 2F 32 30 30 35 2F 30 38 .w3.org/2005/08 2F 61 64 64 72 65 73 73 69 6E 67 2F 61 6E 6F /addressing/ano 6E 79 6D 6F 75 73 3C 2F 61 3A 54 6F 3E 3C 2F nymous</a:To></ 73 3A 48 65 61 64 65 72 3E 3C 73 3A 42 6F 64 s:Header><s:Bod 79 3E 3C 41 64 64 52 65 73 70 6F 6E 73 65 20 y><AddResponse 78 6D 6C 6E 73 3D 22 68 74 74 70 3A 2F 2F 74 xmlns="http://t 65 6D 70 75 72 69 2E 6F 72 67 2F 22 3E 3C 41 empuri.org/"><A 64 64 52 65 73 75 6C 74 3E 33 3C 2F 41 64 64 ddResult>3</Add 52 65 73 75 6C 74 3E 3C 2F 41 64 64 52 65 73 Result></AddRes 70 6F 6E 73 65 3E 3C 2F 73 3A 42 6F 64 79 3E ponse></s:Body> 3C 2F 73 3A 45 6E 76 65 6C 6F 70 65 3E </s:Envelope>[READ] 1 bytes 87 .[WRITE] 1 bytes 07 .
Next time: A Problem with Large Faults