MsmqHostedTransportManager.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ WCF / WCF / 3.5.30729.1 / untmp / Orcas / SP / ndp / cdf / src / WCF / ServiceModel / System / ServiceModel / Channels / MsmqHostedTransportManager.cs / 1 / MsmqHostedTransportManager.cs

                            //---------------------------------------------------------------------------- 
// Copyright (c) Microsoft Corporation.  All rights reserved.
//---------------------------------------------------------------------------

namespace System.ServiceModel.Channels 
{
    using System.Collections.Generic; 
    using System.ServiceModel; 
    using System.Diagnostics;
    using System.IO; 
    using System.Net;
    using System.ServiceModel.Diagnostics;
    using System.Text;
    using System.Threading; 
    using System.Web;
    using System.Web.Hosting; 
    using System.ServiceModel.Activation; 

    class MsmqHostedTransportManager : TransportManager 
    {
        string[] hosts;
        List bindingMonitors;
        HostedBindingFilter filter; 
        MsmqUri.IAddressTranslator addressing;
        MessageReceivedCallback messageReceivedCallback; 
 
        public MsmqHostedTransportManager(string[] hosts, MsmqUri.IAddressTranslator addressing)
        { 
            this.hosts = hosts;
            this.bindingMonitors = new List();
            this.addressing = addressing;
            this.filter = new HostedBindingFilter(HostingEnvironment.ApplicationVirtualPath, addressing); 

            foreach(string host in this.hosts) 
            { 
                MsmqBindingMonitor monitor = new MsmqBindingMonitor(host);
                monitor.AddFilter(this.filter); 

                this.bindingMonitors.Add(monitor);
            }
 
            foreach(MsmqBindingMonitor monitor in this.bindingMonitors)
            { 
                monitor.Open(); 
            }
        } 

        public Uri[] GetBaseAddresses(string virtualPath)
        {
            // Make sure this is not called until initialization is done: 
            foreach(MsmqBindingMonitor monitor in this.bindingMonitors)
            { 
                monitor.WaitForFirstRoundComplete(); 
            }
 
            string absoluteVirtualPath = VirtualPathUtility.ToAbsolute(virtualPath, HostingEnvironment.ApplicationVirtualPath);

            List baseAddresses = new List(this.hosts.Length);
            string queueName = absoluteVirtualPath.Substring(1); 

            foreach(string host in this.hosts) 
            { 
                bool isPrivate = this.filter.IsPrivateMatch(queueName);
 
                Uri uri = this.addressing.CreateUri(host, queueName, isPrivate);
                baseAddresses.Add(uri);
                MsmqDiagnostics.FoundBaseAddress(uri, absoluteVirtualPath);
            } 
            return baseAddresses.ToArray();
        } 
 
        internal override string Scheme
        { 
            get { return this.addressing.Scheme; }
        }

        internal override void OnClose() 
        {
            // Nothing to do - we never use the transport manager during normal 
            // operation. 
        }
 
        internal override void OnOpen()
        {
            // Nothing to do - we only use the transport manager for WebHosted case.
        } 

        internal override void Register(TransportChannelListener channelListener) 
        { 
            channelListener.SetMessageReceivedCallback(new MessageReceivedCallback(OnMessageReceived));
        } 

        internal void Start(MessageReceivedCallback messageReceivedCallback)
        {
            this.messageReceivedCallback = messageReceivedCallback; 
        }
 
        internal override void Unregister(TransportChannelListener channelListener) 
        {
            // Nothing to do - we never use the transport manager during normal 
            // operation.
        }

        void OnMessageReceived() 
        {
            if (messageReceivedCallback != null) 
            { 
                messageReceivedCallback();
            } 
        }

        class HostedBindingFilter : MsmqBindingFilter
        { 
            Dictionary privateMatches = new Dictionary(StringComparer.OrdinalIgnoreCase);
 
            public HostedBindingFilter(string path, MsmqUri.IAddressTranslator addressing) 
              : base(path, addressing)
            { 
            }

            public override object MatchFound(string host, string name, bool isPrivate)
            { 
                string processedVirtualPath = CreateRelativeVirtualPath(host, name, isPrivate);
                string relativeServiceFile = ServiceHostingEnvironment.NormalizeVirtualPath(processedVirtualPath); 
 
                // Compute the remainder path:
                lock(this) 
                {
                    if(isPrivate)
                    {
                        string baseQueue = CreateBaseQueue(relativeServiceFile); 
                        this.privateMatches[baseQueue] = baseQueue;
                    } 
                } 

                // Start the service on a different thread so we can complete 
                // initialization
                if(CheckServiceExists(relativeServiceFile))
                {
                    MsmqDiagnostics.StartingService(host, name, isPrivate, processedVirtualPath); 
                    IOThreadScheduler.ScheduleCallback(StartService, processedVirtualPath);
                } 
 
                // no callback state here...
                return null; 
            }

            public bool IsPrivateMatch(string processedVirtualPath)
            { 
                lock(this)
                { 
                    return this.privateMatches.ContainsKey(processedVirtualPath); 
                }
            } 

            public override void MatchLost(string host, string name, bool isPrivate, object callbackState)
            {
                // We don't do anything here - the service will stay alive, 
                // and if the queue ever comes back, then it will begin to
                // process again. 
            } 

            string CreateRelativeVirtualPath(string host, string name, bool isPrivate) 
            {
                // the canonical prefix looks something like: "invoices/"
                // Because the queue name matched, it looks like "invoices/..."
                // remove the common piece, and prefix with the "~/" home specifier 
                return "~/" + name.Substring(CanonicalPrefix.Length);
            } 
 
            string CreateBaseQueue(string serviceFile)
            { 
                // Clean up the service file...
                if(serviceFile.StartsWith("~", StringComparison.OrdinalIgnoreCase))
                    serviceFile = serviceFile.Substring(1);
                if(serviceFile.StartsWith("/", StringComparison.OrdinalIgnoreCase)) 
                    serviceFile = serviceFile.Substring(1);
 
                string virtualPath = HostingEnvironment.ApplicationVirtualPath; 
                if(virtualPath.EndsWith("/", StringComparison.OrdinalIgnoreCase))
                    virtualPath = virtualPath.Substring(0, virtualPath.Length-1); 
                if(virtualPath.StartsWith("/", StringComparison.OrdinalIgnoreCase))
                    virtualPath = virtualPath.Substring(1);

                return virtualPath + "/" + serviceFile; 
            }
 
            bool CheckServiceExists(string serviceFile) 
            {
                try 
                {
                    return HostingEnvironment.VirtualPathProvider.FileExists(serviceFile);
                }
                catch(ArgumentException ex) 
                {
                    MsmqDiagnostics.ExpectedException(ex); 
                    return false; 
                }
            } 

            void StartService(object state)
            {
                try 
                {
                    string processedVirtualPath = (string)state; 
                    ServiceHostingEnvironment.EnsureServiceAvailable(processedVirtualPath); 
                }
                catch(ServiceActivationException e) 
                {
                    // Non-fatal exceptions from the user code are wrapped in ServiceActivationException
                    // The best we can do is to trace them
                    MsmqDiagnostics.ExpectedException(e); 
                }
                catch(EndpointNotFoundException e) 
                { 
                    // This means that the server disappeared between the time we
                    // saw the service, and the time we tried to start it. 
                    // That's okay.
                    MsmqDiagnostics.ExpectedException(e);
                }
            } 
        }
    } 
} 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK