2015-06-23 3 views
0

Мы используем библиотеку SignalR в нашем веб-приложении ASP.NET. Код выглядит следующим образом:Контактор SignalR на 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

Является ли класс концентратора в другом приложении в качестве вашего контроллера 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)

Я сделал простой пример веб-приложения. Проект имеет класс Hub:

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

Page (Бритва просто чтобы быть в состоянии назвать тренажер, который вызывает переменный ток # класса для отправки сообщения из внутреннего интерфейса):

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

И я добавил фиктивный класс, который запускает событие через hubcontext каждые 5 секунд.

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, добавить несколько точек отладки, это поможет вам понять основы, то это будет намного проще строить, что вы собираетесь строить.

EDIT

О запросе висящей: До тех пор, пока у вас есть клиент, подключенный к серверу SignalR с SSE или AJAX Long-опроса, вы будете иметь постоянный запрос, который никогда не заканчивается. (В случае длинного опроса AJAX он заканчивается очень короткое время и возвращается). В приложениях, где я использую только Javascript-клиенты, я вижу только запрос, если страница открыта, где я слушаю события. Если страница или статическая страница не открываются, то запрос не запрашивается. В приложениях, где я использую .NET-клиенты, пока оба приложения запущены, и оба класса Sartup выполняются, запрос всегда будет там, даже если страница не открывается. (Так как клиент .NET все еще слушает события.)

Для получения дополнительной информации: http://hanselminutes.com/291/damian-edwards-explains-the-realtime-web-for-aspnet-with-signalr

+0

Я прокомментировал вызов Invoke в моем контроллере MVC и попытался использовать ваш статический вызов, но он не работает, и запрос SIgnalR все еще зависает в IIS. С Invoke все работает нормально, но запрос SIgnalR все еще висит на IIS. Моя цель - избавиться от висячего запроса. Почему он висит? – tesicg

+0

Что такое клиентский протокол? – DDan

+0

На самом деле вызов метода контроллера MVC осуществляется из основного приложения ASP.NET таким образом: Get file Контроллер MVC размещается в отдельной DLL. Я не уверен, влияет ли это на проблему. – tesicg

0

Это проблема, связанная Threading. Попробуйте вот так

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

       ..... 

      })).Wait(); 
Смежные вопросы