Пример #1
0
        void AddMetadataEndpoint(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher, bool debugMode)
        {
            Uri baseAddress = endpoint.Address.Uri;

            if (baseAddress == null)
            {
                return;
            }

            ServiceHostBase host = endpointDispatcher.ChannelDispatcher.Host;

            UriBuilder builder = new UriBuilder(baseAddress);

            builder.Path += builder.Path.EndsWith("/", StringComparison.OrdinalIgnoreCase)
                ? (WebScriptClientGenerator.GetMetadataEndpointSuffix(debugMode))
                : ("/" + WebScriptClientGenerator.GetMetadataEndpointSuffix(debugMode));
            EndpointAddress metadataAddress = new EndpointAddress(builder.Uri);

            foreach (ServiceEndpoint serviceEndpoint in host.Description.Endpoints)
            {
                if (EndpointAddress.UriEquals(serviceEndpoint.Address.Uri, metadataAddress.Uri, true, false))//  ignoreCase //  includeHostNameInComparison
                {
                    throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError(
                              new InvalidOperationException(SR2.GetString(SR2.JsonNoEndpointAtMetadataAddress, this.GetType().ToString(), serviceEndpoint.Address, serviceEndpoint.Name, host.Description.Name)));
                }
            }

            HttpTransportBindingElement transportBindingElement;
            HttpTransportBindingElement existingTransportBindingElement = endpoint.Binding.CreateBindingElements().Find <HttpTransportBindingElement>();

            if (existingTransportBindingElement != null)
            {
                transportBindingElement = (HttpTransportBindingElement)existingTransportBindingElement.Clone();
            }
            else
            {
                if (baseAddress.Scheme == "https")
                {
                    transportBindingElement = new HttpsTransportBindingElement();
                }
                else
                {
                    transportBindingElement = new HttpTransportBindingElement();
                }
            }

            transportBindingElement.HostNameComparisonMode = HostNameComparisonMode.StrongWildcard;
            transportBindingElement.TransferMode           = TransferMode.Buffered;
            transportBindingElement.MaxBufferSize          = MaxMetadataEndpointBufferSize;
            transportBindingElement.MaxReceivedMessageSize = MaxMetadataEndpointBufferSize;
            Binding metadataBinding = new CustomBinding(
                new WebScriptMetadataMessageEncodingBindingElement(),
                transportBindingElement);
            BindingParameterCollection parameters = host.GetBindingParameters(endpoint);

            // build endpoint dispatcher
            ContractDescription  metadataContract           = ContractDescription.GetContract(typeof(ServiceMetadataExtension.IHttpGetMetadata));
            OperationDescription metadataOperation          = metadataContract.Operations[0];
            EndpointDispatcher   metadataEndpointDispatcher = new EndpointDispatcher(metadataAddress, metadataContract.Name, metadataContract.Namespace);
            DispatchOperation    dispatchOperation          = new DispatchOperation(metadataEndpointDispatcher.DispatchRuntime, metadataOperation.Name, metadataOperation.Messages[0].Action, metadataOperation.Messages[1].Action);

            dispatchOperation.Formatter = new WebScriptMetadataFormatter();
            dispatchOperation.Invoker   = new SyncMethodInvoker(metadataOperation.SyncMethod);
            metadataEndpointDispatcher.DispatchRuntime.Operations.Add(dispatchOperation);
            metadataEndpointDispatcher.DispatchRuntime.SingletonInstanceContext = new InstanceContext(host, new WebScriptClientGenerator(endpoint, debugMode, !String.IsNullOrEmpty(this.JavascriptCallbackParameterName)));
            metadataEndpointDispatcher.DispatchRuntime.InstanceContextProvider  = new SingletonInstanceContextProvider(metadataEndpointDispatcher.DispatchRuntime);

            // build channel dispatcher
            IChannelListener <IReplyChannel> listener = null;

            if (metadataBinding.CanBuildChannelListener <IReplyChannel>(parameters))
            {
                listener = metadataBinding.BuildChannelListener <IReplyChannel>(metadataAddress.Uri, parameters);
            }
            ChannelDispatcher metadataChannelDispatcher = new ChannelDispatcher(listener);

            metadataChannelDispatcher.MessageVersion = MessageVersion.None;
            metadataChannelDispatcher.Endpoints.Add(metadataEndpointDispatcher);

            host.ChannelDispatchers.Add(metadataChannelDispatcher);
        }
Пример #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);
        }