move to from olive to mcs
[mono.git] / mcs / class / System.ServiceModel / System.ServiceModel.Channels / TcpDuplexSessionChannel.cs
1 // 
2 // TcpDuplexSessionChannel.cs
3 // 
4 // Author: 
5 //     Marcos Cobena (marcoscobena@gmail.com)
6 // 
7 // Copyright 2007 Marcos Cobena (http://www.youcannoteatbits.org/)
8 // 
9
10 using System;
11 using System.IO;
12 using System.Net;
13 using System.Net.Sockets;
14 using System.Runtime.Serialization;
15 using System.Runtime.Serialization.Formatters.Binary;
16 using System.ServiceModel.Channels;
17 using System.Xml;
18
19 namespace System.ServiceModel.Channels
20 {
21         internal class TcpDuplexSessionChannel : DuplexChannelBase, IDuplexSessionChannel
22         {
23
24                 TcpChannelInfo info;
25                 TcpClient client;
26                 bool is_service_side;
27                 EndpointAddress local_address;
28                 EndpointAddress remote_address;
29                 TcpListener tcp_listener;
30                 TimeSpan timeout;
31                 Uri via;
32                 
33                 public TcpDuplexSessionChannel (ChannelFactoryBase factory, TcpChannelInfo info, EndpointAddress address, Uri via)
34                         : base (factory)
35                 {
36                         is_service_side = false;
37                         this.info = info;
38                         remote_address = address;
39                         this.via = via;
40                 }
41                 
42                 public TcpDuplexSessionChannel (ChannelListenerBase listener, TcpChannelInfo info, TcpClient acceptedRequest, TimeSpan timeout)
43                         : base (listener)
44                 {
45                         is_service_side = true;
46                         this.info = info;
47                         this.client = acceptedRequest;
48                         this.timeout = timeout;
49
50                         Stream s = client.GetStream ();
51
52                         //while (s.CanRead)
53                         //      Console.Write ("{0:X02} ", s.ReadByte ());
54                         
55                         for (int i = 0; i < 6; i++)
56                                 s.ReadByte ();
57                         
58                         int size = s.ReadByte ();
59                         
60                         for (int i = 0; i < size; i++)
61                                 s.ReadByte (); // URI
62                         
63                         s.ReadByte ();
64                         s.ReadByte ();
65                         s.ReadByte ();
66                         s.WriteByte (0x0B);
67                 }
68                 
69                 public MessageEncoder Encoder {
70                         get { return info.MessageEncoder; }
71                 }
72
73                 public override EndpointAddress LocalAddress {
74                         get { return local_address; }
75                 }
76                 
77                 public override EndpointAddress RemoteAddress {
78                         get { return remote_address; }
79                 }
80                 
81                 // FIXME: implement
82                 public IDuplexSession Session {
83                         get { throw new NotImplementedException (); }
84                 }
85                 
86                 public override Uri Via {
87                         get { return via; }
88                 }
89                 
90                 [MonoTODO]
91                 public override IAsyncResult BeginSend (Message message, AsyncCallback callback, object state)
92                 {
93                         throw new NotImplementedException ();
94                 }
95                 
96                 [MonoTODO]
97                 public override IAsyncResult BeginSend (Message message, TimeSpan timeout, AsyncCallback callback, object state)
98                 {
99                         throw new NotImplementedException ();
100                 }
101                 
102                 [MonoTODO]
103                 public override void EndSend (IAsyncResult result)
104                 {
105                         throw new NotImplementedException ();
106                 }
107
108                 [MonoTODO]
109                 public override void Send (Message message)
110                 {
111                         MemoryStream ms = new MemoryStream ();
112                         BinaryFormatter bf = new BinaryFormatter ();
113                         
114                         try
115                         {
116                                 NetworkStream stream = client.GetStream ();
117                                 MyBinaryWriter bw = new MyBinaryWriter (stream);
118                                 bw.Write ((byte) 6);
119                                 Encoder.WriteMessage (message, ms);
120                                 bw.WriteBytes (ms.ToArray ());
121                                 bw.Write ((byte) 7);
122                                 bw.Flush ();
123
124                                 stream.ReadByte (); // 7
125                         }
126                         catch (Exception e)
127                         {
128                                 throw e;
129                         }
130                 }
131                 
132                 [MonoTODO]
133                 public override void Send (Message message, TimeSpan timeout)
134                 {
135                         throw new NotImplementedException ();
136                 }
137                 
138                 [MonoTODO]
139                 public override IAsyncResult BeginReceive (AsyncCallback callback, object state)
140                 {
141                         throw new NotImplementedException ();
142                 }
143                 
144                 [MonoTODO]
145                 public override IAsyncResult BeginReceive (TimeSpan timeout, AsyncCallback callback, object state)
146                 {
147                         throw new NotImplementedException ();
148                 }
149                 
150                 [MonoTODO]
151                 public override IAsyncResult BeginTryReceive (TimeSpan timeout, AsyncCallback callback, object state)
152                 {
153                         throw new NotImplementedException ();
154                 }
155                 
156                 [MonoTODO]
157                 public override IAsyncResult BeginWaitForMessage (TimeSpan timeout, AsyncCallback callback, object state)
158                 {
159                         throw new NotImplementedException ();
160                 }
161                 
162                 [MonoTODO]
163                 public override Message EndReceive (IAsyncResult result)
164                 {
165                         throw new NotImplementedException ();
166                 }
167                 
168                 [MonoTODO]
169                 public override bool EndTryReceive (IAsyncResult result, out Message message)
170                 {
171                         throw new NotImplementedException ();
172                 }
173                 
174                 [MonoTODO]
175                 public override bool EndWaitForMessage (IAsyncResult result)
176                 {
177                         throw new NotImplementedException ();
178                 }
179                 
180                 [MonoTODO]
181                 public override Message Receive ()
182                 {
183                         Stream s = client.GetStream ();
184                         s.ReadByte (); // 6
185                         MyBinaryReader br = new MyBinaryReader (s);
186 //                      string msg = br.ReadString ();
187 //                      br.Read7BitEncodedInt ();
188                         byte [] buffer = new byte [65536];
189                         buffer = br.ReadBytes ();
190                         MemoryStream ms = new MemoryStream ();
191                         ms.Write (buffer, 0, buffer.Length);
192                         ms.Seek (0, SeekOrigin.Begin);
193                         
194 //                      while (s.CanRead)
195 //                              Console.Write ("{0:X02} ", s.ReadByte ());
196                         
197                         Message msg = null;
198                         // FIXME: To supply maxSizeOfHeaders.
199                         msg = Encoder.ReadMessage (ms, 0x10000);
200                         s.ReadByte (); // 7
201 //                      Console.WriteLine (msg);
202                         s.WriteByte (7);
203                         s.Flush ();
204
205                         return msg;
206                 }
207                 
208                 [MonoTODO]
209                 public override Message Receive (TimeSpan timeout)
210                 {
211                         throw new NotImplementedException ();
212                 }
213                 
214                 [MonoTODO]
215                 public override bool TryReceive (TimeSpan timeout, out Message message)
216                 {
217                         throw new NotImplementedException ();
218                 }
219                 
220                 [MonoTODO]
221                 public override bool WaitForMessage (TimeSpan timeout)
222                 {
223                         throw new NotImplementedException ();
224                 }
225                 
226                 // CommunicationObject
227                 
228                 [MonoTODO]
229                 protected override void OnAbort ()
230                 {
231                         throw new NotImplementedException ();
232                 }
233
234                 [MonoTODO]
235                 protected override IAsyncResult OnBeginClose (TimeSpan timeout,
236                         AsyncCallback callback, object state)
237                 {
238                         throw new NotImplementedException ();
239                 }
240
241                 [MonoTODO]
242                 protected override IAsyncResult OnBeginOpen (TimeSpan timeout,
243                         AsyncCallback callback, object state)
244                 {
245                         throw new NotImplementedException ();
246                 }
247
248                 [MonoTODO]
249                 protected override void OnClose (TimeSpan timeout)
250                 {
251                         client.Close ();
252                 }
253                 
254                 [MonoTODO]
255                 protected override void OnEndClose (IAsyncResult result)
256                 {
257                         throw new NotImplementedException ();
258                 }
259
260                 [MonoTODO]
261                 protected override void OnEndOpen (IAsyncResult result)
262                 {
263                         throw new NotImplementedException ();
264                 }
265                 
266                 [MonoTODO]
267                 protected override void OnOpen (TimeSpan timeout)
268                 {
269                         if (! is_service_side) {
270                                 int explicitPort = RemoteAddress.Uri.Port;
271                                 client = new TcpClient (RemoteAddress.Uri.Host, explicitPort <= 0 ? TcpTransportBindingElement.DefaultPort : explicitPort);
272                                                         //RemoteAddress.Uri.Port);
273                                 
274                                 NetworkStream ns = client.GetStream ();
275                                 ns.WriteByte (0);
276                                 ns.WriteByte (1);
277                                 ns.WriteByte (0);
278                                 ns.WriteByte (1);
279                                 ns.WriteByte (2);
280                                 ns.WriteByte (2);
281                                 byte [] bytes = System.Text.Encoding.UTF8.GetBytes (RemoteAddress.Uri.ToString ());
282                                 ns.WriteByte ((byte) bytes.Length);
283                                 ns.Write (bytes, 0, bytes.Length);
284                                 ns.WriteByte (3);
285                                 ns.WriteByte (3);
286                                 ns.WriteByte (0xC);
287                                 int hoge = ns.ReadByte ();
288                                 //while (ns.CanRead)
289                                 //      Console.Write ("{0:X02} ", ns.ReadByte ());
290                         }
291                         // Service side.
292                         /*
293                         else
294                                 Console.WriteLine ("Server side.");
295                         */
296                 }
297                 
298                 // FIXME: To look for other way to do this.
299                 class MyBinaryReader : BinaryReader
300                 {
301                         public MyBinaryReader (Stream s)
302                                 : base (s)
303                         {
304                         }
305                         
306                         public byte [] ReadBytes ()
307                         {
308                                 byte [] buffer = new byte [65536];
309                                 int length = Read7BitEncodedInt ();
310                                 
311                                 if (length > 65536)
312                                         throw new InvalidOperationException ("The message is too large.");
313                                 
314                                 Read (buffer, 0, length);
315                                 
316                                 return buffer;
317                         }
318                 }
319                 
320                 class MyBinaryWriter : BinaryWriter
321                 {
322                         public MyBinaryWriter (Stream s)
323                                 : base (s)
324                         {
325                         }
326                         
327                         public void WriteBytes (byte [] bytes)
328                         {
329                                 Write7BitEncodedInt (bytes.Length);
330                                 Write (bytes);
331                         }
332                 }
333         }
334 }