2 // System.Runtime.Remoting.Channels.ChannelServices.cs
4 // Author: Rodrigo Moya (rodrigo@ximian.com)
5 // Dietmar Maurer (dietmar@ximian.com)
6 // Lluis Sanchez Gual (lluis@ideary.com)
8 // 2002 (C) Copyright, Ximian, Inc.
11 using System.Collections;
12 using System.Runtime.Remoting;
13 using System.Runtime.Remoting.Channels;
14 using System.Runtime.Remoting.Messaging;
15 using System.Runtime.Remoting.Contexts;
17 namespace System.Runtime.Remoting
20 internal class ChannelInfo : IChannelInfo
22 object [] channelData = null;
26 channelData = ChannelServices.GetCurrentChannelInfo ();
29 public ChannelInfo (object remoteChannelData)
31 channelData = new object[] { remoteChannelData };
34 public object[] ChannelData
47 namespace System.Runtime.Remoting.Channels
49 public sealed class ChannelServices
51 private static ArrayList registeredChannels = new ArrayList ();
52 private static CrossContextChannel _crossContextSink = new CrossContextChannel();
54 internal static string CrossContextUrl = "__CrossContext";
56 private ChannelServices ()
60 internal static CrossContextChannel CrossContextChannel
62 get { return _crossContextSink; }
65 internal static IMessageSink CreateClientChannelSinkChain(string url, object remoteChannelData, out string objectUri)
67 // Locate a channel that can parse the url. This channel will be used to
68 // create the sink chain.
70 object[] channelDataArray = (object[])remoteChannelData;
72 foreach (IChannel c in registeredChannels)
74 IChannelSender sender = c as IChannelSender;
75 if (c == null) continue;
77 if (channelDataArray == null) {
78 IMessageSink sink = sender.CreateMessageSink (url, null, out objectUri);
79 if (sink != null) return sink; // URL is ok, this is the channel and the sink
82 foreach (object data in channelDataArray) {
83 IMessageSink sink = sender.CreateMessageSink (url, data, out objectUri);
84 if (sink != null) return sink;
92 public static IChannel[] RegisteredChannels
95 IChannel[] channels = new IChannel[registeredChannels.Count];
97 for (int i = 0; i < registeredChannels.Count; i++)
98 channels[i] = (IChannel) registeredChannels[i];
105 public static IMessageCtrl AsyncDispatchMessage (IMessage msg,
106 IMessageSink replySink)
108 throw new NotImplementedException ();
111 public static IServerChannelSink CreateServerChannelSinkChain (
112 IServerChannelSinkProvider provider, IChannelReceiver channel)
114 IServerChannelSinkProvider tmp = provider;
115 while (tmp.Next != null) tmp = tmp.Next;
116 tmp.Next = new ServerDispatchSinkProvider ();
118 // Every provider has to call CreateSink() of its next provider
119 return provider.CreateSink (channel);
123 public static ServerProcessing DispatchMessage (
124 IServerChannelSinkStack sinkStack,
126 out IMessage replyMsg)
128 // TODO: Async processing
130 replyMsg = SyncDispatchMessage (msg);
132 if (RemotingServices.IsOneWay (((IMethodMessage) msg).MethodBase))
133 return ServerProcessing.OneWay;
135 return ServerProcessing.Complete;
138 public static IChannel GetChannel (string name)
140 foreach (IChannel chnl in registeredChannels) {
141 if (chnl.ChannelName == name && !(chnl is CrossAppDomainChannel)) return chnl;
147 public static IDictionary GetChannelSinkProperties (object obj)
149 throw new NotImplementedException ();
152 public static string[] GetUrlsForObject (MarshalByRefObject obj)
154 string uri = RemotingServices.GetObjectUri (obj);
155 if (uri == null) return new string [0];
157 ArrayList list = new ArrayList ();
159 foreach (object chnl_obj in registeredChannels) {
160 if (chnl_obj is CrossAppDomainChannel) continue;
162 IChannelReceiver chnl = chnl_obj as IChannelReceiver;
165 list.AddRange (chnl.GetUrlsForUri (uri));
168 return (string[]) list.ToArray (typeof(string));
171 public static void RegisterChannel (IChannel chnl)
173 // Put the channel in the correct place according to its priority.
174 // Since there are not many channels, a linear search is ok.
176 for (int n = 0; n < registeredChannels.Count; n++) {
177 if ( ((IChannel)registeredChannels[n]).ChannelPriority < chnl.ChannelPriority)
179 registeredChannels.Insert (n, chnl);
183 registeredChannels.Add (chnl);
186 public static IMessage SyncDispatchMessage (IMessage msg)
188 IMethodMessage call = (IMethodMessage)msg;
189 ServerIdentity identity = RemotingServices.GetIdentityForUri(call.Uri) as ServerIdentity;
190 if (identity == null) return new ReturnMessage (new RemotingException ("No receiver for uri " + call.Uri), (IMethodCallMessage) msg);
192 RemotingServices.SetMessageTargetIdentity (msg, identity);
193 return _crossContextSink.SyncProcessMessage (msg);
196 public static void UnregisterChannel (IChannel chnl)
199 throw new ArgumentNullException ();
200 if (!registeredChannels.Contains ((object) chnl))
201 throw new RemotingException ();
203 registeredChannels.Remove ((object) chnl);
205 IChannelReceiver chnlReceiver = chnl as IChannelReceiver;
206 if(chnlReceiver != null)
207 chnlReceiver.StopListening(null);
210 internal static object [] GetCurrentChannelInfo ()
212 ArrayList list = new ArrayList ();
214 foreach (object chnl_obj in registeredChannels) {
215 IChannelReceiver chnl = chnl_obj as IChannelReceiver;
218 object chnl_data = chnl.ChannelData;
219 if (chnl_data != null)
220 list.Add (chnl_data);
224 return list.ToArray ();