2015-06-23 68 views
0

我们在ASP.NET web应用程序中使用SignalR库。代码看起来如下:SignalR hub挂在IIS上

服务器:

[HubName("ticketsCounterHub")] 
public class MassivePrintHub : Hub 
{ 
    public void PostTicketsCount(long count) 
    { 
     Clients.All.Send(count); 
    } 
} 

public class HubFactory 
{ 
    private HubFactory() {} 

    public static readonly HubFactory Current = new HubFactory(); 

    public IHubProxy GetMassivePrintHubProxy() 
    { 
     var hubConnection = new HubConnection(ConfigUtils.GetRequiredSettingValue("adminPath")); 
     var hubProxy = hubConnection.CreateHubProxy("ticketsCounterHub"); 
     hubConnection.Start().Wait(); 
     return hubProxy; 
    } 
} 

客户端(JavaScript的):

MassivePrintApp.controller("ListController", function ($scope, Dates) { 
    var hubManager = (function() { 
     var massivePrintHub = $.connection.ticketsCounterHub; 
     $.connection.hub.start(); 
     return { massivePrintHub: massivePrintHub }; 
    }()); 

    hubManager.massivePrintHub.client.Send = function (ticketsCount) { 
     $scope.action.Quantity = ticketsCount; 
     $scope.$digest(); 
    }; 
}); 

代码的关键部分是在MVC控制器:

public FileResult PrintAction(int actionId, int count, DateTime actionDate, bool isThermo=false) 
{ 
    var ticketsCount = _ticketService.GetTicketsInStatusCount(actionId, actionDate, TicketStatusEnum.ToPrint); 

    HubFactory.Current.GetMassivePrintHubProxy().Invoke("PostTicketsCount", ticketsCount); 

    var stream = new MemoryStream(); 
    xmlResponse.Save(stream); 
    stream.Flush(); 
    stream.Position = 0; 
    return File(stream,ContentTypeEnum.XML.ToString(),String.Format("массовая {0} мероприятия {1} {2}шт.xml", isThermo?"термопечать":"печать", action.Artist,count)); 
} 

正如你可以看到,我们有这条线:

HubFactory.Current.GetMassivePrintHubProxy().Invoke("PostTicketsCount", ticketsCount); 

而这会导致问题,即无论何时我们称之为集线器的一个实例已添加到IIS上的“请求”部分。

我知道我们已经在JavaScript代码中启动了集线器,但我不知道如何使用现有连接或如何摆脱HubFactory或删除创建的集线器实例。

我不明白为什么集线器挂在IIS上。

+0

Hub类与您的MVC控制器在不同的应用程序中吗?如果不是,那么不用创建hubproxy,你可以通过集线器上下文来调用:http://www.asp.net/signalr/overview/guide-to-the-api/hubs-api-guide-server#callfromoutsidehub – DDan

+0

MVC控制器放置在主ASP.NET应用程序使用的依赖项目中。我已经尝试以这种方式使用集线器上下文: IHubContext context = GlobalHost.ConnectionManager.GetHubContext (); context.Clients.All.Send(ticketsCount); 但它不起作用。也许我做错了什么。 – tesicg

+0

集线器也放置在另一个项目中。 – tesicg

回答

1

从一个更简单的例子开始,我会猜到很多。之后,你可以看看你的主机服务器SignalR不同(控制台应用程序或Windows服务)的基本原理不会改变

(先装SignalR:的NuGet:install-package Microsoft.AspNet.SignalR

我做了一个简单的web应用程序的例子。该项目具有轮毂类:

using Microsoft.AspNet.SignalR; 
using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Web; 

namespace SRTest 
{ 
    public class MassivePrintHub : Hub 
    { 
     private static IHubContext hubContext = GlobalHost.ConnectionManager.GetHubContext<MassivePrintHub>(); 

     // Can be called from your Javascript code 
     public void PostTicketsCount(long count) 
     { 
      Clients.All.Send(count); 
     } 

     // Can be called from your c# code 
     public static void Static_PostTicketsCount(long count) 
     { 
      hubContext.Clients.All.Send(count); 
     } 
    } 
} 

的Owin启动类:

using Microsoft.AspNet.SignalR; 
using Microsoft.Owin; 
using Owin; 

[assembly: OwinStartup(typeof(SRTest.Startup))] 
namespace SRTest 
{ 
    public class Startup 
    { 
     public void Configuration(IAppBuilder app) 
     { 
      var hubConfiguration = new HubConfiguration(); 
      hubConfiguration.EnableDetailedErrors = true; 
      app.MapSignalR(hubConfiguration); 
     } 
    } 
} 

页(剃刀只是为了能够调用它调用C#类从后台发布消息的模拟器):

<!DOCTYPE html> 
<html xmlns="http://www.w3.org/1999/xhtml"> 
<head> 
    <title>TEST PAGE</title> 

    <!--Reference the jQuery library. --> 
    <script src='Scripts/jquery-1.6.4.js'></script> 
    <!--Reference the SignalR library. --> 
    <script src='Scripts/jquery.signalR-2.2.0.js'></script> 
    <!--Reference the autogenerated SignalR hub script. --> 
    <script src="signalr/hubs"></script> 

</head> 
<body> 

    THIS IS A TEST PAGE 
    <!-- Call simulator (trigger event every 5 seconds) --> 
    @{SRTest.SendFromBackEnd.SimulateSend();} 

<script> 
    $(function() { 
     var printHub = $.connection.massivePrintHub; 

     // when send event happens 
     printHub.client.send = function (count) { 
      console.log("Send " + count + " tickets"); 
     }; 

     $.connection.hub.start().done(function() { 
      console.log("Connected"); 
     }); 

     $.connection.hub.logging = true; 
    }); 
</script> 

</body> 
</html> 

我添加了一个虚拟类,每隔5秒通过hubcontext触发事件。

using System.Threading; 
using System.Web; 

namespace SRTest 
{ 
    public class SendFromBackEnd 
    { 
     public static void SimulateSend() 
     { 
      new Thread(() => 
      { 
       Thread.CurrentThread.IsBackground = true; 
       while (true) 
       { 
        MassivePrintHub.Static_PostTicketsCount(2); 
        Thread.Sleep(5000); 
       } 
      }).Start(); 

     } 
    } 
} 

我加了一些测井公司在SignalR,添加一些调试点,它会帮助你了解的基础知识,那么这将是更容易建立你正在筹建。

编辑

关于悬挂的要求:只要你有连接到与上证所或AJAX长轮询您SignalR服务器的客户端,你将有一个持续的请求,这永远不会完成。 (如果是AJAX Long-polling,它会在很短的时间内完成并返回)。在仅使用Javascript客户端的应用程序中,如果页面处于打开状态并且正在侦听事件的位置,我才会看到该请求。如果没有页面或静态页面打开,则没有请求。 在我使用.NET客户端的应用程序中,只要两个应用程序正在运行,并且两个Sartup类都已执行,即使没有打开任何页面,请求也会始终存在。 (由于.NET客户端仍在监听事件。)

欲了解更多信息:http://hanselminutes.com/291/damian-edwards-explains-the-realtime-web-for-aspnet-with-signalr

+0

我已经注释掉了在我的MVC控制器中的调用调用,并试图使用您的静态调用,但它不起作用,并且SIgnalR请求仍挂在IIS上。调用一切工作正常,但SIgnalR请求仍挂在IIS上。我的目标是摆脱悬挂的请求。它为什么悬挂? – tesicg

+0

什么是客户端协议? – DDan

+0

实际上,MVC控制器的方法调用是通过这种方式从主ASP.NET应用程序完成的: Get file MVC控制器放置在单独的DLL中。 我不确定这是否会影响问题。 – tesicg

0

这是一个线程相关的问题。像这样尝试

Task.Run(() => connection.Start().ContinueWith(task => 
      { 

       ..... 

      })).Wait();