Beispiel #1
0
        private static Type[] GetSupportedChannelTypes(ContractDescription contractDescription)
        {
            if (contractDescription == null)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException(nameof(contractDescription)));
            }

            ChannelRequirements reqs;

            ChannelRequirements.ComputeContractRequirements(contractDescription, out reqs);
            Type[] supportedChannels = ChannelRequirements.ComputeRequiredChannels(ref reqs);
            // supportedChannels is client-side, need to make server-side
            for (int i = 0; i < supportedChannels.Length; i++)
            {
                if (supportedChannels[i] == typeof(IRequestChannel))
                {
                    supportedChannels[i] = typeof(IReplyChannel);
                }
                else if (supportedChannels[i] == typeof(IRequestSessionChannel))
                {
                    supportedChannels[i] = typeof(IReplySessionChannel);
                }
                else if (supportedChannels[i] == typeof(IOutputChannel))
                {
                    supportedChannels[i] = typeof(IInputChannel);
                }
                else if (supportedChannels[i] == typeof(IOutputSessionChannel))
                {
                    supportedChannels[i] = typeof(IInputSessionChannel);
                }
                else if (supportedChannels[i] == typeof(IDuplexChannel))
                {
                    // no-op; duplex is its own dual
                }
                else if (supportedChannels[i] == typeof(IDuplexSessionChannel))
                {
                    // no-op; duplex is its own dual
                }
                else
                {
                    throw Fx.AssertAndThrowFatal("DispatcherBuilder.GetSupportedChannelTypes: Unexpected channel type");
                }
            }

            return(supportedChannels);
        }
Beispiel #2
0
        Type BuildChannelListener(StuffPerListenUriInfo stuff,
                                  ServiceHostBase serviceHost,
                                  Uri listenUri,
                                  ListenUriMode listenUriMode,
                                  out IChannelListener result)
        {
            Binding       originalBinding         = stuff.Endpoints[0].Binding;
            CustomBinding binding                 = new CustomBinding(originalBinding);
            BindingParameterCollection parameters = stuff.Parameters;

            Uri    listenUriBaseAddress;
            string listenUriRelativeAddress;

            GetBaseAndRelativeAddresses(serviceHost, listenUri, binding.Scheme, out listenUriBaseAddress, out listenUriRelativeAddress);

            // I don't believe InternalDuplexBindingElement is needed, at least not initially.
            // It looks like it's used when a channel factory is used to supply the outgoing channel
            // for duplex. I think it binds an incoming listener to an outgoing channel to acheive duplex.
            //InternalDuplexBindingElement internalDuplex = null;
            //InternalDuplexBindingElement.AddDuplexListenerSupport(binding, ref internalDuplex);

            // All types are supported to start
            bool   reply                = true;
            bool   replySession         = true;
            bool   input                = true;
            bool   inputSession         = true;
            bool   duplex               = true;
            bool   duplexSession        = true;
            string sessionContractName  = null;
            string datagramContractName = null;

            // each endpoint adds constraints
            for (int i = 0; i < stuff.Endpoints.Count; ++i)
            {
                ContractDescription contract = stuff.Endpoints[i].Contract;
                if (contract.SessionMode == SessionMode.Required)
                {
                    sessionContractName = contract.Name;
                }
                if (contract.SessionMode == SessionMode.NotAllowed)
                {
                    datagramContractName = contract.Name;
                }

                System.Collections.IList endpointTypes = GetSupportedChannelTypes(contract);
                if (!endpointTypes.Contains(typeof(IReplyChannel)))
                {
                    reply = false;
                }
                if (!endpointTypes.Contains(typeof(IReplySessionChannel)))
                {
                    replySession = false;
                }
                if (!endpointTypes.Contains(typeof(IInputChannel)))
                {
                    input = false;
                }
                if (!endpointTypes.Contains(typeof(IInputSessionChannel)))
                {
                    inputSession = false;
                }
                if (!endpointTypes.Contains(typeof(IDuplexChannel)))
                {
                    duplex = false;
                }
                if (!endpointTypes.Contains(typeof(IDuplexSessionChannel)))
                {
                    duplexSession = false;
                }
            }

            if ((sessionContractName != null) && (datagramContractName != null))
            {
                string    text  = SR.Format(SR.SFxCannotRequireBothSessionAndDatagram3, datagramContractName, sessionContractName, binding.Name);
                Exception error = new InvalidOperationException(text);
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(error);
            }

            List <Type> supportedChannelTypes = new List <Type>();

            if (input)
            {
                supportedChannelTypes.Add(typeof(IInputChannel));
            }
            if (inputSession)
            {
                supportedChannelTypes.Add(typeof(IInputSessionChannel));
            }
            if (reply)
            {
                supportedChannelTypes.Add(typeof(IReplyChannel));
            }
            if (replySession)
            {
                supportedChannelTypes.Add(typeof(IReplySessionChannel));
            }
            if (duplex)
            {
                supportedChannelTypes.Add(typeof(IDuplexChannel));
            }
            if (duplexSession)
            {
                supportedChannelTypes.Add(typeof(IDuplexSessionChannel));
            }
            // now we know what channel types we can use to support the contracts at this ListenUri
            Type returnValue = MaybeCreateListener(true, supportedChannelTypes.ToArray(), binding, parameters,
                                                   listenUriBaseAddress, listenUriRelativeAddress, listenUriMode, out result);

            if (result == null)
            {
                // we put a lot of work into creating a good error message, as this is a common case
                Dictionary <Type, byte> setOfChannelTypesSupportedByBinding = new Dictionary <Type, byte>();
                if (binding.CanBuildChannelListener <IInputChannel>())
                {
                    setOfChannelTypesSupportedByBinding.Add(typeof(IInputChannel), 0);
                }
                if (binding.CanBuildChannelListener <IReplyChannel>())
                {
                    setOfChannelTypesSupportedByBinding.Add(typeof(IReplyChannel), 0);
                }
                if (binding.CanBuildChannelListener <IDuplexChannel>())
                {
                    setOfChannelTypesSupportedByBinding.Add(typeof(IDuplexChannel), 0);
                }
                if (binding.CanBuildChannelListener <IInputSessionChannel>())
                {
                    setOfChannelTypesSupportedByBinding.Add(typeof(IInputSessionChannel), 0);
                }
                if (binding.CanBuildChannelListener <IReplySessionChannel>())
                {
                    setOfChannelTypesSupportedByBinding.Add(typeof(IReplySessionChannel), 0);
                }
                if (binding.CanBuildChannelListener <IDuplexSessionChannel>())
                {
                    setOfChannelTypesSupportedByBinding.Add(typeof(IDuplexSessionChannel), 0);
                }

                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(ChannelRequirements.CantCreateListenerException(
                                                                              setOfChannelTypesSupportedByBinding.Keys, supportedChannelTypes, originalBinding.Name));
            }
            return(returnValue);
        }