2015-05-20 14 views
8

Ho sperimentato con SignalR oggi ed è davvero pulito. Fondamentalmente quello che volevo ottenere è il seguente:SignalR - Invia messaggio OnConnected

Non appena un dispositivo si connette dovrebbe inviare un messaggio al primo. Se ci sono più dispositivi di 1 collegato, vorrei inviare due messaggi. Uno a tutti eccetto l'ultimo client connesso. E un messaggio a solo l'ultimo client connesso.

Il codice che ho utilizzato funziona perfettamente quando lo inserisco in un controller API personalizzato e fondamentalmente richiamo l'azione, ma non è quello che voglio.

Desidero inviare i messaggi non appena un dispositivo si connette entro OnConnected senza alcuna interazione da parte dell'utente, ma quando inserisco il mio codice all'interno della forzatura OnConnected, smette di funzionare. Non invia più ai client specifici (prima connesso e ultimo connesso).

Spero che qualcuno sia in grado di aiutarmi con questo, perché ho battuto la testa per un paio d'ore.

public override System.Threading.Tasks.Task OnConnected() 
    { 
     UserHandler.ConnectedIds.Add(Context.ConnectionId, UserHandler.ConnectedIds.Count + 1); 

     int amountOfConnections = UserHandler.ConnectedIds.Count; 
     var lastConnection = UserHandler.ConnectedIds.OrderBy(x => x.Value).LastOrDefault(); 
     var allExceptLast = UserHandler.ConnectedIds.Take(amountOfConnections - 1).Select(x => x.Key).ToList(); 

     if (amountOfConnections == 1) 
     { 
      Clients.Client(UserHandler.ConnectedIds.First().Key).hello("Send to only(also first) one"); 
     } 
     else 
     { 
      Clients.Clients(allExceptLast).hello("Send to everyone except last"); 
      Clients.Client(lastConnection.Key).hello("Send to only the last one"); 
     } 

     return base.OnConnected(); 
    } 

risposta

4

Grazie per tutto l'aiuto (hai svalutato ragazzi). In realtà ho trovato il problema ... era dentro il mio cliente. Per prima cosa ho sottoscritto la funzione "ciao" e successivamente ho avviato HubConnection. Non appena ho cambiato questo ordine, tutto ha funzionato bene.

Ha funzionato con il seguente codice client:

private async Task ConnectToSignalR() 
    { 
     var hubConnection = new HubConnection("url"); 
     hubConnection.Headers["x-zumo-application"] = "clientapikey"; 

     IHubProxy proxy = hubConnection.CreateHubProxy("ChatHub"); 

     proxy.On<string>("hello", async (msg) => 
     { 
      Console.WriteLine(msg); 
     }); 

     await hubConnection.Start(); 
    } 
1

bene ... si restituisce un compito ... quindi penso che potrebbe essere il problema ... si deve prima eseguire il codice e quindi restituire il compito ... o mettere un ContinueWith. .. come ...

public override Task OnConnected() 
    { 
     Task task = new Task(() => 
      { 
       UserHandler.ConnectedIds.Add(Context.ConnectionId, UserHandler.ConnectedIds.Count + 1); 

       int amountOfConnections = UserHandler.ConnectedIds.Count; 
       var lastConnection = UserHandler.ConnectedIds.OrderBy(x => x.Value).LastOrDefault(); 
       var allExceptLast = UserHandler.ConnectedIds.Take(amountOfConnections - 1).Select(x => x.Key).ToList(); 

       if (amountOfConnections == 1) 
       { 
        Clients.Client(UserHandler.ConnectedIds.First().Key).hello("Send to only(also first) one"); 
       } 
       else 
       { 
        Clients.Clients(allExceptLast).hello("Send to everyone except last"); 
        Clients.Client(lastConnection.Key).hello("Send to only the last one"); 
       } 
      }); 

     task.ContinueWith(base.OnConnected()); 

     return task; 
    } 

ho non testato che ... il suo solo una supposizione ..

3

Dal momento che non è stata ancora stabilita una connessione, cercando di chiamare la funzione client .hello() all'interno OnConnected non è possibile a questo punto. Tuttavia, possiamo definire un metodo di hub del server e chiamarlo immediatamente alla nostra connessione .done callback. Quindi, nel nostro nuovo metodo server, possiamo riallocare la logica attualmente presente in OnConnected.

Questo cambierà la nostra messa a punto un po 'e introdurre alcuni ulteriori passaggi, ma osservare il seguente esempio ...

// WhateverHub 
public override Task OnConnected() 
{ 
    return base.OnConnected() 
} 

public void AfterConnected() 
{ 
    // if(stuff) -- whatever if/else first user/last user logic 
    // { 
     Clients.Caller.hello("message") 
    // } 
} 

var proxy= $.connection.whateverHub; 

proxy.client.hello = function(message) { 
    // last step in event chain 
} 

$.connection.hub.start().done(function() { 
    proxy.server.afterConnected() // call AfterConnected() on hub 
}); 

Quindi l'idea di base è di prima

  1. Connect =>.done(function() { ... });
  2. Chiama server.afterConnected()
  3. eseguire la logica all'interno di tale metodo
  4. Se siamo soddisfatti con le condizioni di chiamare la nostra funzione .hello() cliente

Nota - questa implementazione è per un cliente JavaScript - ma la stessa idea può essere tradotto in un client .net Questo è principalmente un problema architettonico.

10

A meno che non mi manca qualcosa dalla tua domanda, la soluzione sembra piuttosto semplice per me, non vi resta che passare ad usare

Clients.Caller.hello("Send to only the last one"); 

invece di cercare di capire se stessi che è l'ultimo id collegato. Lo stesso vale per gli altri, è possibile utilizzare:

Clients.Others.hello("Send to everyone except last"); 

non avete bisogno di tutta la logica si imposta, queste 2 righe fanno quello che ti serve, e funzionano all'interno OnConnected.

+0

grazie molto per questo codice. In realtà rende il mio codice molto più semplice! – Mittchel

Problemi correlati