ROT 128 Stream Upgrade Sample, Part 5
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">https://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>https://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">https://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">https://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="https://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