Creating a hub is the easy part - getting the bootstrapper to load the hub took me a while.

Basically you need two things:
  1. Create a class inheriting from the Hub class
  2. Add an assembly tag in the web.config

Basic Hub class

taken from the EventReceiver example:
public class DocLibHub : Hub
    {

        public enum EventType
        {
            Added,
            Updated,
            Deleted
        }
    }


in short you need a public class - the enum is not needed at all. If you add public methods they will show up in the /signalr/hubs javascript (proxy auto generation) and you can use it on the client.

Without methods it will look like this:
spsignalr_hubs.png

Add the assembly tag to the web.config

You can add a tag with the assembly full name to the web.config - this means that the assembly is loaded when the app pool spins up.

There are bad ways to do this (manually) or good and maintainable ways (SPWebconfigModification).
Too make it easy I created a reusable class - just add it to a feature EventReceiver:

private void RegisterHttpModule(SPFeatureReceiverProperties properties)
        {
            SPWebConfigModification webConfigModification = CreateWebModificationObject();

            //this is a webapp feature
            SPWebApplication webapp = properties.Feature.Parent as SPWebApplication;

            if (webapp != null)
            {
                webapp.WebConfigModifications.Add(webConfigModification);
                webapp.Update();
                webapp.WebService.ApplyWebConfigModifications();
                webapp.WebService.Update();
            }
        }

        /// <summary>
        /// Create the SPWebConfigModification object for the assembly
        /// </summary>
        /// <returns>SPWebConfigModification object for adding the download tracking http module to the web.config</returns>
        private SPWebConfigModification CreateWebModificationObject()
        {
            string strUniqueName = string.Format("add[@assembly='{0}']", this.GetType().Assembly.FullName);
            string strNode = "/configuration/system.web/compilation/assemblies";
            SPWebConfigModification webConfigModification = new SPWebConfigModification(strUniqueName, strNode)
            {
                Owner = this.GetType().Assembly.FullName,
                Sequence = 1,
                Type = SPWebConfigModification.SPWebConfigModificationType.EnsureChildNode,
                Value = string.Format("<add assembly='{0}' />", this.GetType().Assembly.FullName)
            };
            return webConfigModification;
        }

        public override void FeatureActivated(SPFeatureReceiverProperties properties)
        {
            RegisterHttpModule(properties);
        }


        // Uncomment the method below to handle the event raised before a feature is deactivated.

        public override void FeatureDeactivating(SPFeatureReceiverProperties properties)
        {
            UnregisterHttpModule(properties);
        }

        private void UnregisterHttpModule(SPFeatureReceiverProperties properties)
        {

            SPWebConfigModification webConfigModification = CreateWebModificationObject();

            SPSecurity.RunWithElevatedPrivileges(() =>
            {
                SPWebService contentService = properties.Definition.Farm.Services.GetValue<SPWebService>();

                int numberOfModifications = contentService.WebConfigModifications.Count;

                /*
                 * Iterate over all WebConfigModification and delete only those we have created
                 */
                for (int i = numberOfModifications - 1; i >= 0; i--)
                {
                    SPWebConfigModification currentModifiction = contentService.WebConfigModifications[i];

                    if (currentModifiction.Owner.Equals(webConfigModification.Owner))
                    {
                        contentService.WebConfigModifications.Remove(currentModifiction);
                    }
                }

                /*
                 * Update only if we have something deleted
                 */
                if (numberOfModifications > contentService.WebConfigModifications.Count)
                {
                    contentService.Update();
                    contentService.ApplyWebConfigModifications();
                }

            });
        }


Important: The feature has to be WebApplication scoped - this ensure that its only activated once per WebApplication/web.config.

Last edited Apr 2, 2013 at 7:49 AM by MaxMelcher, version 2

Comments

No comments yet.