Condividi tramite


Il presente articolo è stato tradotto automaticamente.

Cutting Edge

Polling esteso e SignalR

Dino Esposito

 

Dino EspositoStiamo costruendo più sofisticate applicazioni Web su un protocollo che, paradossalmente, è stato concepito e progettato per molto più semplici forme di interazione. HTTP non ha nessun supporto incorporato per stato o anche sicurezza. Presupposto di base è che il cliente inserisce una richiesta e il server Web problemi una risposta. In sintesi, questo significa nessuna richiesta, nessuna risposta.

Data l'attuale penetrazione del Web e l'onnipresenza delle soluzioni Web, cambiare i pilastri del Web (HTTP, HTML, JavaScript) è esclusa. Ma dovremmo considerare migliorare alcune di tali pilastri? Naturalmente. Applicazioni moderne hanno requisiti specifici che spingono i protocolli Web e lingue al loro limite — o di là.

Nelle versioni recenti di questa colonna, ho parlato di un'implementazione artigianale di un meccanismo che esegue il polling del server e segnala le modifiche al client. Il mese scorso, ho implementato la stessa idea di utilizzare i servizi di una libreria emergente — SignalR. Ora provvederemo a fornire una breve panoramica delle tecniche e una sintesi delle opzioni che hanno oggi. Sarò messo SignalR sotto i riflettori e guardare la sua attuazione — e alcuni della sua magia.

Considerazioni di polling

Dato il vincolo di richiesta/risposta HTTP, polling è l'unico modo per impostare la comunicazione diretta tra un client e un server Web. Il client spinge le richieste alla sua convenienza e il server risponde diligentemente. La chiave per la valutazione dell'efficacia dei seggi è il significato effettivo che si assegna all'espressione "a suo piacimento." C'è sempre una richiesta del client, al centro di qualsiasi soluzione basata su seggi. La richiesta si erge fino a quando il server ha risposto. Qualsiasi richiesta in sospeso consuma una connessione browser e, cosa ancora più importante, si aggancia un thread server, rendendo disponibili per altre richieste da tale risorsa preziosa. In poche parole, troppo frequenti richieste costruire pressione sul server Web.

Ma non è la capacità del server di gestire un numero crescente di richieste l'intera idea di scalabilità? In realtà, polling non crea nuove preoccupazioni di scalabilità, ma aggiunge un numero considerevole di nuove richieste al server che devono essere presi in considerazione per assicurare un server scalabile e ad alte prestazioni. Vediamo come noi potremmo realizzare sondaggi.

AJAX Polling

Nel mio dicembre 2011 (msdn.microsoft.com/magazine/hh580729) e il gennaio 2012 (msdn.microsoft.com/magazine/hh708746) colonne, ho presentato un quadro per controllare l'avanzamento di un'operazione di remota. L'intero quadro era basato su AJAX chiamate. In primo luogo, il cliente invoca un endpoint del server per avviare un'attività potenzialmente lunga; Successivamente, imposta un timer per effettuare chiamate simultanee a un altro endpoint ogni 500 millisecondi. Quando l'attività del server fa il suo lavoro, aggiorna un percorso noto. L'endpoint del server che ha invocato periodicamente semplicemente controlli per i dati in quella posizione e restituisce qualsiasi contenuto trova al client.

Questo modello di polling basato su AJAX funziona a meraviglia ed è largamente impiegato in molti scenari di industria. La maggior parte dei siti che forniscono aggiornamenti di notizie o livescore seguono questo modello. Nei miei articoli, ho semplicemente adattato il pattern allo scenario specifico di monitorare l'avanzamento di un'operazione di remota.

Alla fine, il problema con sondaggi AJAX è capire l'intervallo di aggiornamento giusto — uno che rappresenti un buon equilibrio tra la pressione sul server e accuratezza delle informazioni riportate agli utenti. Una soluzione efficace di polling basato su AJAX dà un significato concreto alla "presso del client convenienza" l'invio di richieste.

Polling lungo

Prima di AJAX, gli sviluppatori utilizzato il refresh meta tag HTML per istruire il browser per aggiornare una pagina ogni determinato numero di secondi. Con sondaggi AJAX, raggiungere la stessa cosa, ma in modo molto più agevole.

Per un numero crescente di applicazioni, tuttavia, questa forma di polling non basta. Polling AJAX introduce quasi inevitabilmente un ritardo tra il verificarsi di un evento sul server e la notifica dell'evento al client. Di sintonizzazione alla frequenza degli aggiornamenti, è possibile lavorare le buone soluzioni, eppure polling AJAX non può produrre tale connessione costante e continua che molte applicazioni (per lo più sociale) sembrano bisogno oggi.

La soluzione di questi giorni sembra essere lunga di polling. Curiosamente, quando emerse anni fa, e AJAX polling più intelligente di AJAX sostituito di polling lungo perché quest'ultimo non era molto efficacia sul Web. Tempo di polling è circa fare sul Web le stesse cose che fare in uno scenario di desktop. Con lunghe seggi, il client luoghi la richiesta e il server non risposta fino a quando non dispone di informazioni da restituire. Il client Web mantiene una connessione in sospeso che è chiuso solo quando qualche risposta valida può essere restituito. Questo è esattamente ciò che si vuole oggi — tranne che ha il potenziale di rallentamento del server Web.

Tempo di polling pone un numero inferiore di richieste al server rispetto ai seggi di AJAX, ma ogni richiesta potrebbe richiedere molto più tempo. Nel corso del tempo, questo può essere dannoso per la salute del server Web perché mantiene server thread impegnato fino a quando una risposta può essere generata. Con un minor numero thread di lavoro disponibili in un dato momento, il server Web inevitabilmente ottiene più lenti nel rispondere a tutte le altre richieste si riceve. Per essere efficaci, di polling lungo ha bisogno qualche lavoro serio di implementazione e avanzate competenze di programmazione multithread e parallele. Così, per anni, tempo di polling non era davvero un'opzione, ma non importava perché non non c'era alcuna domanda di connettività continua.

Oggi, con la libreria di attività parallele in Microsoft.NET Framework 4 e altri servizi in ASP.NET per la creazione di gestori HTTP asincroni, lunghi di polling è diventata una valida opzione. In generale, la fabbricazione manuale un quadro di polling lungo è ancora più dura di un quadro di polling basato su AJAX corrispondente. Hai bisogno di un ambiente server ben congegnati che non fiscale del server Web e un ambiente client in grado di supportare lungo di polling. Tempo di polling, infatti, si riferisce ad un'operazione di client/server di macro che si sviluppa attraverso il Web e necessariamente su un numero di pacchetti di richiesta/risposta HTTP classici. Il client deve essere abbastanza intelligente per una nuova richiesta di immediata (ristampa) fino a quando termina l'operazione di macro. Tornerò a questo punto più avanti.

SignalR alla riscossa

SignalR è un framework di Microsoft, specificamente progettato per facilitare la comunicazione client/server in tempo reale. Esso fornisce un'implementazione efficacia di lunga di polling che non ha un profondo impatto sul server e allo stesso tempo garantisce ai clienti in modo adeguato aggiornamento su quello che sta succedendo in remoto. Figura 1mostra un estratto dal codice che ho presentato nel mio ultimo articolo. La classe BookingHub è il metodo che richiamare dal browser Web per avviare l'operazione di macro "prenotare il volo".

Figura 1 SignalR classe che esegue un'operazione di Multistep

public class BookingHub : Hub
{
  public void BookFlight(String from, String to)
  {
    // Book first leg
    Clients.displayMessage(
      String.Format("Booking flight: {0}-{1} ...", from, to));
    BookFlightInternal(from, to);
    // Book return
    Clients.displayMessage(
      String.Format("Booking flight: {0}-{1} ...", to, from));
    BookFlightInternal(to, from);
    // Book return
    Clients.displayMessage("Charging credit card ...");
    ChargeCreditCardInternal();
    // Some return value
    Clients.displayMessage("Flight booked successfully.");
  }
}

Si tratta chiaramente di un'operazione più fasi, e per ogni passaggio della classe invia una notifica al client. Quante richieste HTTP sono coinvolti? Diamo un'occhiata con Fiddler (vedere Figura 2).

The Full Stack of HTTP Requests for the Flight-Booking Operation
Figura 2 lo Stack completo di richieste HTTP per l'operazione di prenotazione del volo

All'interno di un'operazione SignalR

La prima richiesta viene attivata quando si chiama il metodo di avvio da pagina client; Questo identifica il client al back-end SignalR. Va notato che la prima richiesta è una richiesta speciale di negoziazione. Sarà sempre AJAX indipendentemente il trasporto finale negoziato per la connessione. Qualsiasi pagina SignalR Web include codice simile al seguente che viene eseguito quando viene caricata una pagina:

$(function () {
  var bookingHub = $.connection.bookingHub;
  bookingHub.start();
}

In questo modo, la pagina dichiara la sua intenzione di aprire una connessione per richiamare i servizi dell'oggetto bookingHub lato server. Da notare che è SignalR che fa la magia della creazione di un oggetto client secondo la l'interfaccia pubblica dell'oggetto lato server di hub. Il nome dell'oggetto JavaScript corrisponde al nome dell'oggetto server. Tuttavia, è possibile utilizzare l'attributo HubName per modificare il nome in uso sul client:

[HubName("booking")]
public class BookingHub : Hub
{
  ...
}

La richiesta di avvio restituisce un ID client che passerà il client insieme a eventuali richieste successive.

{"Url":"/signalr","connectionId":"2a119962-edf7-4a97-954b-e74f2f1d27a9"}

Successivamente, la libreria client pone un'altra richiesta di connessione. Questa è la richiesta di "collegare", che si tradurrà nell'evento OnConnect fatti valere per la connessione sul server. Figura 3 mostra un paio di richieste di connessione.

Reiterating Connection Requests
Figura 3 ribadendo le richieste di connessione

Il primo completato in due minuti; il secondo è ancora in sospeso. Questa è l'essenza di lunga di polling — il client dispone di un canale aperto continuamente con il server. Il server volte fuori la richiesta dopo due minuti se nessuna azione viene eseguita sul server che richiede l'invio dei dati al client. Nell'applicazione di prenotazione del volo dell'interfaccia utente, c'è un pulsante che l'utente può fare clic per iniziare la prenotazione del volo. Quando l'utente fa clic sul pulsante esegue il codice seguente:

bookingHub.bookFlight("fco", "jfk");

Se l'applicazione di esempio creato dall'articolo del mese scorso, hai dovrebbe collegato questo codice al gestore click del pulsante pagina.

L'oggetto bookingHub appartiene a uno script che SignalR download tramite l'URL signalr-mozzi, come mostrato nella Figura 3. bookingHub è un oggetto proxy pianura che nasconde la complessità dell'implementazione di un modello di polling lungo. Facendo clic sul pulsante Avvia una nuova richiesta al server in cui è incorporato l'ID del client. Quando il server riceve una chiamata da un client che ha una chiamata in attesa, che termina la chiamata in attesa e inizia l'elaborazione della richiesta di nuova, come illustrato nella Figura 4.

A Multistep Operation Is Taking Place
Figura 4 multifasico operazione è in atto

Figura 4 mostra una richiesta in sospeso (signalr/invio), due richieste completate e un'altra richiesta in sospeso. Signalr/Invia richiesta è la chiamata originale all'operazione per prenotare il volo, il cui codice sorgente è illustrata nella macro Figura 1.

Il codice in Figura 1 chiama il cliente nelle varie fasi per la notifica di qualsiasi progresso, in questo modo:

Clients.displayMessage(...);

Allo stesso tempo che una richiesta per signalr/Invia è posto, un'altra richiesta comincia ad aspettare per le notifiche. Questa richiesta attende fino a quando non ci sono alcuni dati di mandare indietro. Tutte le chiamate a clienti in codice server completa la richiesta di notifica e immediatamente fa scattare un altro uno dal client, così la sequenza in Figura 4 significa che due passi sono state completate e due messaggi progressi sono stati ricevuti dal client. Il processo del server è ora occupato cercando di realizzare il terzo gradino. Entro la fine del codice in Figura 1, tutte le richieste in Figura 4 sarà completata e la situazione tornerà a uno simile a quanto riportato nella Figura 2.

Di là di Polling lungo

Se si confronta il comportamento di lunga di polling per come è implementato in SignalR con i passi avevo indicato nei miei articoli su sondaggi AJAX, si dovrebbe riconoscere uno schema comune — il modello indicatore di progresso. AJAX polling e tempo di polling sono due diverse implementazioni del modello stesso. Quale è più efficacia dipende dalla configurazione del server Web e i requisiti dell'applicazione. È la vostra chiamata. In ogni caso, se si opta per il polling lungo, è necessario SignalR o una libreria di analoga. Se si desidera generare il proprio framework, consigliamo di optare per le chiamate di numerosi-ma-rapido di polling AJAX contro le chiamate più lunghe meno-ma di lunga di polling.

Costruire un quadro di polling lungo efficace può essere ingannevole. Con sondaggi AJAX probabilmente non si ottiene connettività continua, ma non rischiate anche rallentare il server. Con questo in mente, io probabilmente non andare in giro e aggiornare qualsiasi server Web in tempo reale che i take care of a SignalR. Tuttavia, una volta che viene rilasciato SignalR, io non vedo alcun motivo per non usarlo per nuove applicazioni.

Infine, è degno di nota che SignalR ora supporta altri trasporti più alto livello oltre a lungo polling. Nell'origine più recente, anche trovare il supporto per WebSockets sui server Windows 8; Server ha inviato gli eventi su Chrome, Firefox, Opera e Safari; e per sempre di Frame su Internet Explorer. La biblioteca comincia all'inizio dell'elenco e continua a cadere indietro finché non viene trovato un trasporto supportato. Così, alla fine, lunga di polling verrà effettivamente raramente utilizzato nella maggior parte dei casi.

Dino Esposito   è l'autore di "programmazione ASP.NET 4 "(Microsoft Press, 2011) e"programmazione ASP.NET MVC 3 "(Microsoft Press, 2010) e coautore di"Microsoft.NET: Architecting Applications for the Enterprise" (Microsoft Press, 2008). Vive in Italia e partecipa spesso come relatore a eventi del settore in tutto il mondo. Seguirlo su Twitter a Twitter.com/despos.

Grazie all'esperto tecnica seguente per la revisione di questo articolo: Damian Edwards