2009-05-26 Atsushi Enomoto <atsushi@ximian.com>
[mono.git] / mcs / class / System.ServiceModel / System.ServiceModel.Channels / TcpChannelListener.cs
1 // 
2 // TcpChannelListener.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.Collections.Generic;
12 using System.IO;
13 using System.Net;
14 using System.Net.Sockets;
15 using System.ServiceModel.Description;
16 using System.Text;
17 using System.Xml;
18
19 namespace System.ServiceModel.Channels
20 {
21         internal class TcpChannelListener<TChannel> : ChannelListenerBase<TChannel> 
22                 where TChannel : class, IChannel
23         {
24                 List<IChannel> channels = new List<IChannel> ();
25                 BindingContext context;
26                 TcpChannelInfo info;
27                 IDuplexSession session;
28                 Uri listen_uri;
29                 TcpListener tcp_listener;
30                 
31                 [MonoTODO]
32                 public TcpChannelListener (TcpTransportBindingElement source, 
33                                            BindingContext context) : base (context.Binding)
34                 {
35                         MessageEncoder encoder = null;
36                         XmlDictionaryReaderQuotas quotas = null;
37
38                         if (context.ListenUriMode == ListenUriMode.Explicit)
39                                 listen_uri =
40                                         context.ListenUriRelativeAddress != null ?
41                                         new Uri (context.ListenUriBaseAddress, context.ListenUriRelativeAddress) :
42                                         context.ListenUriBaseAddress;
43                         else
44                                 throw new NotImplementedException ();
45                         
46                         foreach (BindingElement be in context.RemainingBindingElements) {
47                                 MessageEncodingBindingElement mbe = be as MessageEncodingBindingElement;
48                                 if (mbe != null) {
49                                         encoder = CreateEncoder<TChannel> (mbe);
50                                         quotas = mbe.GetProperty<XmlDictionaryReaderQuotas> (context);
51                                         break;
52                                 }
53                         }
54                         
55                         if (encoder == null)
56                                 encoder = new BinaryMessageEncoder ();
57
58                         info = new TcpChannelInfo (source, encoder, quotas);
59                 }
60                 
61                 public override Uri Uri {
62                         get { return listen_uri; }
63                 }
64                 
65                 [MonoTODO]
66                 protected override TChannel OnAcceptChannel (TimeSpan timeout)
67                 {
68                         TChannel channel = PopulateChannel (timeout);
69                         channels.Add (channel);
70                         return channel;
71                 }
72                 
73                 TChannel PopulateChannel (TimeSpan timeout)
74                 {
75                         // FIXME: pass delegate or something to remove the channel instance from "channels" when it is closed.
76                         if (typeof (TChannel) == typeof (IDuplexSessionChannel))
77                                 return (TChannel) (object) new TcpDuplexSessionChannel (this, info, tcp_listener, timeout);
78
79                         // FIXME: To implement more.
80                         throw new NotImplementedException ();
81                 }
82
83                 [MonoTODO]
84                 protected override IAsyncResult OnBeginAcceptChannel (TimeSpan timeout,
85                         AsyncCallback callback, object asyncState)
86                 {
87                         throw new NotImplementedException ();
88                 }
89
90                 [MonoTODO]
91                 protected override TChannel OnEndAcceptChannel (IAsyncResult result)
92                 {
93                         throw new NotImplementedException ();
94                 }
95                 
96                 [MonoTODO]
97                 protected override IAsyncResult OnBeginWaitForChannel (
98                         TimeSpan timeout, AsyncCallback callback, object state)
99                 {
100                         throw new NotImplementedException ();
101                 }
102
103                 [MonoTODO]
104                 protected override bool OnEndWaitForChannel (IAsyncResult result)
105                 {
106                         throw new NotImplementedException ();
107                 }
108
109                 [MonoTODO]
110                 protected override bool OnWaitForChannel (TimeSpan timeout)
111                 {
112                         throw new NotImplementedException ();
113                 }
114                 
115                 // CommunicationObject
116                 
117                 [MonoTODO]
118                 protected override void OnAbort ()
119                 {
120                         throw new NotImplementedException ();
121                 }
122
123                 [MonoTODO]
124                 protected override IAsyncResult OnBeginClose (TimeSpan timeout,
125                         AsyncCallback callback, object state)
126                 {
127                         throw new NotImplementedException ();
128                 }
129
130                 [MonoTODO]
131                 protected override IAsyncResult OnBeginOpen (TimeSpan timeout,
132                         AsyncCallback callback, object state)
133                 {
134                         throw new NotImplementedException ();
135                 }
136
137                 [MonoTODO]
138                 protected override void OnClose (TimeSpan timeout)
139                 {
140                         tcp_listener.Stop ();
141                         tcp_listener = null;
142                 }
143                 
144                 [MonoTODO]
145                 protected override void OnEndClose (IAsyncResult result)
146                 {
147                         throw new NotImplementedException ();
148                 }
149
150                 [MonoTODO]
151                 protected override void OnEndOpen (IAsyncResult result)
152                 {
153                         throw new NotImplementedException ();
154                 }
155                 
156                 [MonoTODO]
157                 protected override void OnOpen (TimeSpan timeout)
158                 {
159                         IPHostEntry entry = Dns.GetHostEntry (listen_uri.Host);
160                         
161                         if (entry.AddressList.Length ==0)
162                                 throw new ArgumentException (String.Format ("Invalid listen URI: {0}", listen_uri));
163                         
164                         int explicitPort = listen_uri.Port;
165                         tcp_listener = new TcpListener (entry.AddressList [0], explicitPort <= 0 ? TcpTransportBindingElement.DefaultPort : explicitPort);
166                         tcp_listener.Start ();
167                 }
168         }
169 }