2015-09-09 18 views
6

Attualmente sto utilizzando SignalR per comunicare tra un server e più processi separati generati dal server stesso. Entrambi i client del server & sono codificati in C#. Sto usando SignalR 2.2.0.0 Sul lato server, utilizzo OWIN per eseguire il server. Sto anche usando LightInject come un contenitore IoC.SignalR server -> chiamata client non funzionante

Ecco il mio codice:

public class AgentManagementStartup 
{ 
    public void ConfigurationOwin(IAppBuilder app, IAgentManagerDataStore dataStore) 
    { 
     var serializer = new JsonSerializer 
     { 
      PreserveReferencesHandling = PreserveReferencesHandling.Objects, 
      TypeNameHandling = TypeNameHandling.Auto, 
      TypeNameAssemblyFormat = FormatterAssemblyStyle.Simple 
     }; 

     var container = new ServiceContainer(); 
     container.RegisterInstance(dataStore); 
     container.RegisterInstance(serializer); 
     container.Register<EventHub>(); 
     container.Register<ManagementHub>(); 
     var config = container.EnableSignalR(); 

     app.MapSignalR("", config); 
    } 
} 

Sul lato client, mi iscrivo in questo modo:

public async Task Connect() 
{ 
    try 
    { 
     m_hubConnection = new HubConnection(m_serverUrl, false); 
     m_hubConnection.Closed += OnConnectionClosed; 
     m_hubConnection.TraceLevel = TraceLevels.All; 
     m_hubConnection.TraceWriter = Console.Out; 

     var serializer = m_hubConnection.JsonSerializer; 
     serializer.TypeNameHandling = TypeNameHandling.Auto; 
     serializer.PreserveReferencesHandling = PreserveReferencesHandling.Objects; 

     m_managementHubProxy = m_hubConnection.CreateHubProxy(AgentConstants.ManagementHub.Name); 
     m_managementHubProxy.On("closeRequested", CloseRequestedCallback); 

     await m_hubConnection.Start(); 
    } 
    catch (Exception e) 
    { 
     m_logger.Error("Exception encountered in Connect method", e); 
    } 
} 

Sul lato server mando una richiesta stretta seguente modo:

var managementHub = GlobalHost.ConnectionManager.GetHubContext<ManagementHub>(); 
managementHub.Clients.All.closeRequested(); 

Non ricevo mai alcuna richiamata in CloseRequestedCallback. Né sul lato client né sul lato server ricevo errori nei log.

Cosa ho fatto di sbagliato qui?

EDIT 09/10/15

Dopo alcune ricerche e modifiche, ho scoperto che è stato collegato con la sostituzione del contenitore CIO. Quando ho rimosso tutto collegato a LightInject e utilizzato SignalR così com'è, tutto ha funzionato. Sono stato sorpreso da LightInject documented their integration con SignalR.

Dopo aver trovato questo, mi sono reso conto che il GlobalHost.DependencyResolver non era lo stesso di quello che fornivo allo HubConfiguration. Una volta ho aggiunto

GlobalHost.DependencyResolver = config.Resolver; 

prima

app.MapSignalR("", config); 

ora sto ricevendo le richiamate all'interno CloseRequestedCallback. Purtroppo, ottengo il seguente errore non appena io chiamo un metodo dal client al server:

Microsoft.AspNet.SignalR.Client.Infrastructure.SlowCallbackException

Possibile stallo rilevato. Un callback registrato con "HubProxy.On" o "Connection.Received" è in esecuzione da almeno 10 secondi.

Non sono sicuro della correzione trovata e dell'impatto che potrebbe avere sul sistema. È corretto sostituire il GlobalHost.DependencyResolver con il mio senza registrare tutto il suo contenuto predefinito?

EDIT 2 09/10/15

Secondo this, cambiando la GlobalHost.DependencyResolver è la cosa giusta da fare. Ancora lasciato senza spiegazione per il SlowCallbackException poiché non faccio nulla in tutti i miei callback (ancora).

+0

In relazione al callback lento, forse è necessario eseguire quel processo lento [in background] (http://www.hanselman.com/blog/HowToRunBackgroundTasksInASPNET.aspx) e utilizzare semplicemente SignalR per avviare l'attività ? Ad ogni modo, questo è un problema separato. Sposta la tua soluzione IoC fuori dalla tua domanda e rispondi. Quindi, se necessario, crea una nuova domanda per il tuo callback lento. – mason

+0

@mason: non ho processi lunghi da eseguire in nessuno dei miei callback (lato client e server). Ecco perché sono sorpreso di ricevere questo errore. Capisco il tuo punto nel mantenere la domanda all'interno dello stesso argomento, ma il problema sembra correlato. – KOTIX

risposta

3

Problema 1: IoC Container + Dependency Injection

Se si desidera cambiare il CIO per voi HubConfiguration, è anche bisogno di cambiare quello della GlobalHost in modo che restituisce lo stesso mozzo quando ne facciano richiesta ouside di contesto.

Problema 2: SlowCallbackException imprevisto

Questa eccezione è stata causata dal fatto che stavo usando SignalR all'interno di un'applicazione console. Il punto di ingresso del l'applicazione non può essere un metodo async in modo da essere in grado di chiamare la mia configurazione iniziale in modo asincrono che ho fatto come segue:

private static int Main() 
{ 
    var t = InitAsync(); 
    t.Wait(); 
    return t.Result; 
} 

Purtroppo per me, questo provoca un sacco di problemi, come descritto here & più in dettaglio here.

Avviando il mio InitAsync come segue:

private static int Main() 
{ 
    Task.Factory.StartNew(async()=> await InitAsync()); 
    m_waitInitCompletedRequest.WaitOne(TimeSpan.FromSeconds(30)); 
    return (int)EndpointErrorCode.Ended; 
} 

Tutto ora funziona bene e non ho ricevuto alcun deadlock.

Per ulteriori dettagli sulle risposte &, è possibile fare riferimento anche alle modifiche nella mia domanda.

Problemi correlati