SignalR在本地IIS上无法工作,但与IIS Express一起可以工作

3
我正在尝试编写一个小的SignalR项目。当该项目设置为在IIS Express下运行时,一切正常。
但是,当我在Visual Studio项目属性中切换到“本地IIS”并尝试运行时,我的页面加载了,但没有连接到SignalR服务器。
我使用Fiddler进行了检查,并发现虽然所有脚本都相对于路径正确加载,但SignalR调用是在网站根目录下进行的。所以在Fiddler中,我看到类似于这样的内容:
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           

正如您所看到的,当项目运行在/TestApp/下时,SignalR会在/signalr上调用它的negotiate函数。

我该如何告诉SignalR查找正确的位置(相对位置)?

编辑

这是我的OwinStartup.cs文件:

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

我在global.asax中没有定义任何内容 - 我需要吗?


你能展示一下你的配置文件吗?你的Global.asax中是否有调用MapHubs的代码呢? - Michael McPherson
@MichaelMcPherson 我已在上面添加了信息。我在我的 global.asax 中没有定义任何内容 - 我应该吗? - developer82
你正在运行什么类型的 Web 应用程序?是空的 Web 应用程序、MVC 还是 WebAPI? - radu-matei
@Matei_Radu 普通的asp.net web应用程序,没有mvc。 - developer82
请问您能提供客户端连接代码吗?谢谢! - radu-matei
啊,忘了关于Global.asax的评论吧;看起来我找到了1.2版本的资源。下面的解决方案应该会指引你朝着正确的方向前进。 - Michael McPherson
4个回答

3

开发者82的回答对我来说不太适用,但我没有足够的积分来评论,所以我将其作为单独的答案提交。我需要像这样指定我的连接:

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

这里的 TestApp 是虚拟目录名称。请注意,我必须将 signalr 显式地添加到末尾。


2

当我切换到本地IIS时,遇到了同样的问题。通过“管理NuGet包”升级到signalR-2.2.0后,我读了这个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.


由于我正在开发一个常规的ASP.NET应用程序,所以我必须更改以下内容:

<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>

转换为:

<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>

之前我添加了一个名为 "Startup.SignalR.cs" 的类文件:

using Owin;
using Microsoft.AspNet.SignalR;

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

我的 Startup.cs 如下所示:

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);            
        }
    }
}

现在在项目/属性中,我可以在调试/生产环境之间切换IIS Express和本地ISS。


0

试试这个:

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

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

现在,这应该告诉您的应用程序将SignalR进程映射到/TestApp物理位置。根据我的经验,使用直接的app.MapSignalR();只有大约30%的成功率,其余的情况下,我必须像上面那样使用显式位置声明。


仍然无法工作。我尝试进行调试并注意到在 IIS 下未调用 OwinStartup。 - developer82
你的应用程序尝试运行的应用程序池是集成的,而不是经典的? - Michael McPherson
是的。我在网上搜索了 - 所有关于同样问题的答案都建议检查这个 - 但仍然不起作用 :( - developer82
你的启动类是一个OWIN启动类,是通过VS创建新对话框创建的吗? - Michael McPherson
哦,好的,你让我有些困惑了。你能在IIS上运行其中一个简单的测试应用程序吗? - Michael McPherson
显示剩余2条评论

0

我找到了一些使其工作的东西。它与OwinStartup中的映射无关(测试后发现,虽然调用了该函数但在调试期间没有停止)。

在查找SignalR的js源文件时,我找到了这个函数,它初始化了一个hub连接:

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);
}

如您所见,它需要一个url参数。因此,当我使用以下代码初始化我的Hub时:

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

现在它可以工作了。现在我只是编写了一个简单的服务器端,检查它是否应该初始化此参数(如果它正在运行在子目录中),并将值注入到HTML页面中。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接