2010-04-06 Jb Evain <jbevain@novell.com>
[mcs.git] / class / System.Runtime.Remoting / System.Runtime.Remoting.Channels.Ipc.Win32 / IpcClientChannel.cs
blob2be59efb57ba4adca48eab1da3b31739dc370160
1 //
2 // System.Runtime.Remoting.Channels.Ipc.Win32.IpcClientChannel.cs
3 //
4 // Author: Robert Jordan (robertj@gmx.net)
5 //
6 // Copyright (C) 2005 Novell, Inc (http://www.novell.com)
7 //
8 //
9 // Permission is hereby granted, free of charge, to any person obtaining
10 // a copy of this software and associated documentation files (the
11 // "Software"), to deal in the Software without restriction, including
12 // without limitation the rights to use, copy, modify, merge, publish,
13 // distribute, sublicense, and/or sell copies of the Software, and to
14 // permit persons to whom the Software is furnished to do so, subject to
15 // the following conditions:
16 //
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
19 //
20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
24 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29 #if NET_2_0
31 using System;
32 using System.Collections;
33 using System.IO;
34 using System.Runtime.Remoting;
35 using System.Runtime.Remoting.Channels;
36 using System.Runtime.Remoting.Messaging;
38 namespace System.Runtime.Remoting.Channels.Ipc.Win32
40 internal class IpcClientChannel : IChannelSender, IChannel
42 readonly string channelName = IpcChannelHelper.Scheme;
43 readonly int channelPriority = 1;
44 readonly IClientChannelSinkProvider clientProvider;
46 /// <summary>
47 /// Creates a default client channel.
48 /// </summary>
49 public IpcClientChannel()
50 : this ((IDictionary)null, null)
54 /// <summary>
55 /// Creates a default client channel.
56 /// </summary>
57 /// <param name="name">The channel name.</param>
58 /// <param name="sinkProvider">The provider</param>
59 public IpcClientChannel(string name, IClientChannelSinkProvider provider)
60 : this (IpcServerChannel.BuildDefaultProperties (name), provider)
64 /// <summary>
65 /// Creates a client channel.
66 /// </summary>
67 /// <param name="properties">The properties.</param>
68 /// <param name="sinkProvider">The provider</param>
69 public IpcClientChannel(IDictionary properties, IClientChannelSinkProvider provider)
71 if (properties != null)
73 foreach (DictionaryEntry e in properties)
75 switch ((string)e.Key)
77 case "name":
78 channelName = (string)e.Value;
79 break;
80 case "priority":
81 channelPriority = Convert.ToInt32(e.Value);
82 break;
87 if (provider == null)
89 clientProvider = new BinaryClientFormatterSinkProvider();
90 clientProvider.Next = new IpcClientChannelSinkProvider();
92 else
94 // add us to the sink chain.
95 clientProvider = provider;
96 IClientChannelSinkProvider p;
97 for (p = clientProvider; p.Next != null; p = p.Next) {}
98 p.Next = new IpcClientChannelSinkProvider();
103 #region IChannelSender Members
105 public IMessageSink CreateMessageSink(string url, object remoteChannelData, out string objectURI)
107 objectURI = null;
108 string channelUri = null;
110 if (url != null)
112 channelUri = Parse(url, out objectURI);
115 if (channelUri == null)
117 // get url from the channel data
118 IChannelDataStore ds = remoteChannelData as IChannelDataStore;
119 if (ds != null)
121 channelUri = Parse(ds.ChannelUris[0], out objectURI);
122 if (channelUri != null)
123 url = ds.ChannelUris[0];
127 if (channelUri != null)
129 return (IMessageSink) clientProvider.CreateSink(this, url, remoteChannelData);
131 else
133 return null;
137 #endregion
139 #region IChannel Members
141 public string ChannelName
145 return channelName;
149 public int ChannelPriority
153 return channelPriority;
157 public string Parse(string url, out string objectURI)
159 return IpcChannelHelper.Parse(url, out objectURI);
162 #endregion
165 internal class IpcClientChannelSinkProvider : IClientChannelSinkProvider
167 #region IClientChannelSinkProvider Members
169 public IClientChannelSink CreateSink(IChannelSender channel, string url, object remoteChannelData)
171 return new IpcClientChannelSink(url);
174 public IClientChannelSinkProvider Next
178 return null;
182 throw new NotSupportedException();
186 #endregion
189 internal class IpcClientChannelSink : IClientChannelSink
191 readonly string pipeName;
193 public IpcClientChannelSink(string url)
195 string unused;
196 IpcChannelHelper.Parse(url, out pipeName, out unused);
199 #region IClientChannelSink Members
201 delegate void AsyncResponse(IClientChannelSinkStack sinkStack, IpcTransport transport);
203 public void AsyncProcessRequest(IClientChannelSinkStack sinkStack, IMessage msg, ITransportHeaders headers, Stream stream)
205 headers[CommonTransportKeys.RequestUri] = ((IMethodCallMessage)msg).Uri;
207 // connect
208 NamedPipeClient client = new NamedPipeClient(pipeName);
209 NamedPipeSocket socket = client.Connect();
210 IpcTransport t = new IpcTransport(socket);
211 t.Write(headers, stream);
213 // schedule an async call
214 if (!RemotingServices.IsOneWay(((IMethodCallMessage)msg).MethodBase))
216 new AsyncResponse(AsyncHandler).BeginInvoke(sinkStack, t, null, null);
220 void AsyncHandler(IClientChannelSinkStack sinkStack, IpcTransport transport)
222 try
224 // get the response headers and the response stream from the server
225 ITransportHeaders responseHeaders;
226 Stream responseStream;
227 transport.Read(out responseHeaders, out responseStream);
228 transport.Close();
229 sinkStack.AsyncProcessResponse(responseHeaders, responseStream);
231 catch (Exception ex)
233 sinkStack.DispatchException(ex);
237 public void ProcessMessage(IMessage msg, ITransportHeaders requestHeaders, Stream requestStream, out ITransportHeaders responseHeaders, out Stream responseStream)
239 responseHeaders = null;
240 responseStream = null;
242 requestHeaders[CommonTransportKeys.RequestUri] = ((IMethodCallMessage)msg).Uri;
244 // connect
245 NamedPipeClient client = new NamedPipeClient(pipeName);
246 NamedPipeSocket socket = client.Connect();
247 IpcTransport t = new IpcTransport(socket);
248 t.Write(requestHeaders, requestStream);
249 t.Read(out responseHeaders, out responseStream);
250 t.Close();
253 public void AsyncProcessResponse(IClientResponseChannelSinkStack sinkStack, object state, ITransportHeaders headers, Stream stream)
255 throw new NotSupportedException();
258 public Stream GetRequestStream(IMessage msg, ITransportHeaders headers)
260 return null;
263 public IClientChannelSink NextChannelSink
265 get { return null; }
268 #endregion
270 #region IChannelSinkBase Members
272 public IDictionary Properties
274 get { return null; }
277 #endregion
283 #endif