2 // System.Runtime.Remoting.Channels.Ipc.Win32.IpcClientChannel.cs
4 // Author: Robert Jordan (robertj@gmx.net)
6 // Copyright (C) 2005 Novell, Inc (http://www.novell.com)
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:
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
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.
32 using System.Collections;
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;
47 /// Creates a default client channel.
49 public IpcClientChannel()
50 : this ((IDictionary)null, null)
55 /// Creates a default client channel.
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)
65 /// Creates a client channel.
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)
78 channelName = (string)e.Value;
81 channelPriority = Convert.ToInt32(e.Value);
89 clientProvider = new BinaryClientFormatterSinkProvider();
90 clientProvider.Next = new IpcClientChannelSinkProvider();
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)
108 string channelUri = null;
112 channelUri = Parse(url, out objectURI);
115 if (channelUri == null)
117 // get url from the channel data
118 IChannelDataStore ds = remoteChannelData as IChannelDataStore;
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);
139 #region IChannel Members
141 public string ChannelName
149 public int ChannelPriority
153 return channelPriority;
157 public string Parse(string url, out string objectURI)
159 return IpcChannelHelper.Parse(url, out objectURI);
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
182 throw new NotSupportedException();
189 internal class IpcClientChannelSink : IClientChannelSink
191 readonly string pipeName;
193 public IpcClientChannelSink(string url)
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;
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)
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);
229 sinkStack.AsyncProcessResponse(responseHeaders, responseStream);
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;
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);
253 public void AsyncProcessResponse(IClientResponseChannelSinkStack sinkStack, object state, ITransportHeaders headers, Stream stream)
255 throw new NotSupportedException();
258 public Stream GetRequestStream(IMessage msg, ITransportHeaders headers)
263 public IClientChannelSink NextChannelSink
270 #region IChannelSinkBase Members
272 public IDictionary Properties