Reputation: 13713
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?
Upvotes: 3
Views: 8724
Reputation: 3001
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).
Upvotes: 2
Reputation: 63
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.
Upvotes: 3
Reputation: 13713
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.
Upvotes: 0
Reputation: 498
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.
Upvotes: 0