简体   繁体   中英

SignalR not working on local IIS but working with IIS Express

I'm trying to write a small SignalR project. When the project is set to run under IIS Express everything works as it should.

But when in Visual Studio project properties I switch to "Local IIS" and try to run, my page loads and does not connect to the SignalR Server.

I've checked with Fiddler and I found that while all script are loaded correctly relative to the path, the SignalR calls are made to the root of the website. So in fiddler I see something like this:

3   304 HTTP    localhost   /TestApp/Scripts/jquery-1.10.2.min.js   0           microsoftedgecp:11004           
4   304 HTTP    localhost   /TestApp/Scripts/jquery.signalR-2.1.2.min.js    0           microsoftedgecp:11004           
6   404 HTTP    localhost   /signalr/negotiate?clientProtocol=1.4&connectionData=%5B%7B%22name%22%3A%22testapphub%22%7D%5D&_=1440092162315  4,958   private text/html; charset=utf-8    microsoftedgecp:11004           

As you can see, the SignalR is calling it's negotiate on /signalr while the project is running under /TestApp/

How can I tell it to look at to correct location (relative) ?

Edit

This is my OwinStartup.cs :

public void Configuration(IAppBuilder app)
{
    app.MapSignalR();
}

I have nothing defined in global.asax - should I?

The answer from developer82 didn't quite work for me, but I don't have enough points to comment so I'm submitting it as a separate answer. I needed to specify my connection like this:

var connection = $.hubConnection('/TestApp/signalr');

where TestApp is the virtual directory name. Note that I explicitly had to tack signalr on to the end.

I ran into the same problem when switching to Local IIS. After upgrading to to signalR-2.2.0 via 'Manage NuGet Packages' I did read this readme.txt:

Please see http://go.microsoft.com/fwlink/?LinkId=272764 for more information on using SignalR.

Upgrading from 1.x to 2.0 Please see http://go.microsoft.com/fwlink/?LinkId=320578 for more information on how to upgrade your SignalR 1.x application to 2.0.

Mapping the Hubs connection To enable SignalR in your application, create a class called Startup with the following:

 using Microsoft.Owin; using Owin; using MyWebApplication; namespace MyWebApplication { public class Startup { public void Configuration(IAppBuilder app) { app.MapSignalR(); } } } 

Getting Started See http://www.asp.net/signalr/overview/getting-started for more information on how to get started.

Why does ~/signalr/hubs return 404 or Why do I get a JavaScript error: 'myhub is undefined'? This issue is generally due to a missing or invalid script reference to the auto-generated Hub JavaScript proxy at '~/signalr/hubs'. Please make sure that the Hub route is registered before any other routes in your application.

In ASP.NET MVC 4 you can do the following:

  <script src="~/signalr/hubs"></script> 

If you're writing an ASP.NET MVC 3 application, make sure that you are using Url.Content for your script references:

 <script src="@Url.Content("~/signalr/hubs")"></script> 

If you're writing a regular ASP.NET application use ResolveClientUrl for your script references or register them via the ScriptManager using a app root relative path (starting with a '~/'):

 <script src='<%: ResolveClientUrl("~/signalr/hubs") %>'></script> 

If the above still doesn't work, you may have an issue with routing and extensionless URLs. To fix this, ensure you have the latest patches installed for IIS and ASP.NET.


Since I am working on a regular ASP.NET application, I had to change this:

<script src="/Scripts/jquery-1.10.2.min.js" ></script>
<script src="/Scripts/jquery.signalR-2.1.2.js"></script>
<script src="/signalr/hubs"></script>

to this:

<script src='<%: ResolveClientUrl("~/Scripts/jquery-1.10.2.min.js") %'></script>
<script src='<%: ResolveClientUrl("~/Scripts/jquery.signalR-2.2.0.js") %>'></script>
<script src='<%: ResolveClientUrl("~/signalr/hubs") %>'></script>

Previously I added a class file "Startup.SignalR.cs":

using Owin;
using Microsoft.AspNet.SignalR;

namespace WebApplication1
{
    public partial class Startup
    {
        public void ConfigureSignalR(IAppBuilder app)
        {
            app.MapSignalR();
        }
    }
}

My Startup.cs looks like this:

using Microsoft.Owin;
using Owin;

[assembly: OwinStartupAttribute(typeof(WebApplication1.Startup))]
namespace WebApplication1
{
    public partial class Startup {
        public void Configuration(IAppBuilder app) {
            //System.Diagnostics.Debugger.Break();

            ConfigureSignalR(app);
            ConfigureAuth(app);            
        }
    }
}

Now in Project / Properties I can switch between IIS Express and Local ISS (for debugging / production).

Try this:

public void Configuration(IAppBuilder app)
    {
        var hubConfiguration = new HubConfiguration();
        hubConfiguration.EnableDetailedErrors = true;
        hubConfiguration.EnableJavaScriptProxies = true;

        app.MapSignalR("/TestApp", hubConfiguration);
    }

Now, that should tell your application to map the SignalR process to your /TestApp physical location. In my experience, using the straight app.MapSignalR(); works about 30% of the time, and the rest, I have to use an explicit location declaration like the above.

I've found something that makes it work. It doesn't have to do with mapping in the OwinStartup (which after testing I found that is being called but not braked during debug).

After digging inside the js source file of SignalR I found this function the initializes a hub connection:

function hubConnection(url, options) {
    /// <summary>Creates a new hub connection.</summary>
    /// <param name="url" type="String">[Optional] The hub route url, defaults to "/signalr".</param>
    /// <param name="options" type="Object">[Optional] Settings to use when creating the hubConnection.</param>
    var settings = {
        qs: null,
        logging: false,
        useDefaultPath: true
    };

    $.extend(settings, options);

    if (!url || settings.useDefaultPath) {
        url = (url || "") + "/signalr";
    }
    return new hubConnection.fn.init(url, settings);
}

As you can see, it takes a url parameter. So when I initialized my hub with the following code:

var connection = $.hubConnection('/TestApp/');

It now works. Now I just wrote a simple server side that checks weather it should initialize this parameter (if it's running in a sub-directory) and inject the value to the HTML page.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM