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