/// <summary> /// Method mostly copied from Microsoft.AspNet.SignalR OwinExtensions class, but without external dependency on Katana. /// </summary> /// <param name="configuration">The <see cref="HubConfiguration"/> to use.</param> /// <param name="startupEnv">Startup parameters.</param> /// <param name="next">Next <see cref="AppFunc"/> in pipeline.</param> /// <returns><see cref="AppFunc"/> ready for use.</returns> public static Func <IDictionary <string, object>, Task> BuildHubFunc(HubConfiguration configuration, IDictionary <string, object> startupEnv, AppFunc next) { if (configuration == null) { throw new ArgumentException("No configuration provided"); } var resolver = configuration.Resolver; if (resolver == null) { throw new ArgumentException("No dependency resolver provider"); } var token = startupEnv.GetValueOrDefault("owin.CallCancelled", CancellationToken.None); string instanceName = startupEnv.GetValueOrDefault("host.AppName", Guid.NewGuid().ToString()); var protectedData = new DefaultProtectedData(); resolver.Register(typeof(IProtectedData), () => protectedData); // If the host provides trace output then add a default trace listener var traceOutput = startupEnv.GetValueOrDefault("host.TraceOutput", (TextWriter)null); if (traceOutput != null) { var hostTraceListener = new TextWriterTraceListener(traceOutput); var traceManager = new TraceManager(hostTraceListener); resolver.Register(typeof(ITraceManager), () => traceManager); } // Try to get the list of reference assemblies from the host IEnumerable <Assembly> referenceAssemblies = startupEnv.GetValueOrDefault("host.ReferencedAssemblies", (IEnumerable <Assembly>)null); if (referenceAssemblies != null) { // Use this list as the assembly locator var assemblyLocator = new EnumerableOfAssemblyLocator(referenceAssemblies); resolver.Register(typeof(IAssemblyLocator), () => assemblyLocator); } resolver.InitializeHost(instanceName, token); var hub = new HubDispatcherMiddleware(new KatanaShim(next), configuration); return(async env => { await hub.Invoke(new OwinContext(env)); if (!env.ContainsKey("owin.ResponseStatusCode")) { env["owin.ResponseStatusCode"] = 200; } }); }
private static IAppBuilder UseSignalRMiddleware <T>(this IAppBuilder builder, params object[] args) { ConnectionConfiguration configuration = null; // Ensure we have the conversions for MS.Owin so that // the app builder respects the OwinMiddleware base class SignatureConversions.AddConversions(builder); if (args.Length > 0) { configuration = args[args.Length - 1] as ConnectionConfiguration; if (configuration == null) { throw new ArgumentException(Resources.Error_NoConfiguration); } var resolver = configuration.Resolver; if (resolver == null) { throw new ArgumentException(Resources.Error_NoDependencyResolver); } var env = builder.Properties; CancellationToken token = env.GetShutdownToken(); // If we don't get a valid instance name then generate a random one string instanceName = env.GetAppInstanceName() ?? Guid.NewGuid().ToString(); // Use the data protection provider from app builder and fallback to the // Dpapi provider IDataProtectionProvider provider = builder.GetDataProtectionProvider(); IProtectedData protectedData; // If we're using DPAPI then fallback to the default protected data if running // on mono since it doesn't support any of this if (provider == null && MonoUtility.IsRunningMono) { protectedData = new DefaultProtectedData(); } else { if (provider == null) { provider = new DpapiDataProtectionProvider(instanceName); } protectedData = new DataProtectionProviderProtectedData(provider); } resolver.Register(typeof(IProtectedData), () => protectedData); // If the host provides trace output then add a default trace listener TextWriter traceOutput = env.GetTraceOutput(); if (traceOutput != null) { var hostTraceListener = new TextWriterTraceListener(traceOutput); var traceManager = new TraceManager(hostTraceListener); resolver.Register(typeof(ITraceManager), () => traceManager); } // Try to get the list of reference assemblies from the host IEnumerable <Assembly> referenceAssemblies = env.GetReferenceAssemblies(); if (referenceAssemblies != null) { // Use this list as the assembly locator var assemblyLocator = new EnumerableOfAssemblyLocator(referenceAssemblies); resolver.Register(typeof(IAssemblyLocator), () => assemblyLocator); } resolver.InitializeHost(instanceName, token); } builder.Use(typeof(T), args); // BUG 2306: We need to make that SignalR runs before any handlers are // mapped in the IIS pipeline so that we avoid side effects like // session being enabled. The session behavior can be // manually overridden if user calls SetSessionStateBehavior but that shouldn't // be a problem most of the time. builder.UseStageMarker(PipelineStage.PostAuthorize); return(builder); }