Le prestazioni sono l'unico motivo per non utilizzare SignalR (websocket) al posto di un'API REST tradizionale?


42

Ho usato SignalRper ottenere funzionalità di messaggistica in tempo reale in molti dei miei progetti. Sembra funzionare in modo affidabile ed è molto facile da imparare a usare.

La tentazione, almeno per me, è di abbandonare lo sviluppo di un servizio API Web e utilizzarlo SignalRper tutto.

Sento che questo potrebbe essere ottenuto con una progettazione ponderata e, se lo fosse, significherebbe che sarebbe necessario molto meno codice client. Ancora più importante, significherebbe che ci sarebbe una singola interfaccia per i servizi piuttosto che un'interfaccia divisa, e nel peggiore dei casi, si potrebbe collegarlo senza pensare a quando le cose vengono rese, ecc.

Quindi, vorrei sapere:

  1. Esistono altri motivi per non utilizzare SignalR al posto di tutti i servizi Web oltre alle prestazioni?
  2. Le prestazioni di SignalR sono sufficientemente preoccupanti da non avere senso farlo?

È stato a lungo un mio sogno poter tradurre le definizioni di oggetti e servizi sul lato server in codice di accesso al servizio sul lato client senza qualcosa di stupido node.js. Ad esempio, se definisco un oggetto interessante InterestingObjecte un servizio per CRUDl'oggetto InterestingObjectService, posso definire una route URL standard per il servizio, ad esempio "/ {serviceName} / {methodName}" - ma devo ancora scrivere il codice client per accedere il servizio. Poiché l'oggetto verrà passato dal client al server e viceversa, non vi è alcun motivo pratico per avereper definire l'oggetto in modo esplicito nel codice lato client, né dovrebbe essere necessario definire esplicitamente le route per eseguire operazioni CRUD. Sento che dovrebbe esserci un modo per standardizzare tutto ciò in modo che sia possibile scrivere un client partendo dal presupposto che l'accesso al servizio funzioni dal client al server e viceversa in modo trasparente come se stessi scrivendo un WinForms o Java Applet o App nativa o cosa hai.

Se SignalR è abbastanza buono da usare al posto di un servizio web tradizionale, potrebbe essere un modo fattibile per raggiungere questo obiettivo. SignalR include già funzionalità per far funzionare l'hub come il servizio che descrivo, in modo da poter definire un servizio di base comune (CRUD) che offrirebbe tutte queste funzionalità pronte all'uso con qualche riflessione. Quindi potrei quasi dare per scontato l'accesso al servizio, risparmiandomi il fastidio di riscrivere il codice per accedere a qualcosa a cui si poteva accedere per convenzione - e, soprattutto, il tempo che avrei dovuto dedicare alla scrittura del codice per definire come questo viene aggiornato in il DOM.

Dopo aver letto la mia modifica, penso che potrebbe essere un po 'assurdo, quindi non esitare a chiedermi se hai domande su cosa sto ricevendo. Fondamentalmente, voglio che l'accesso al servizio sia il più trasparente possibile.


5
Se hai una scheda di rete magica che può contenere un numero infinito di socket e una rete magica in grado di supportare una quantità infinita di larghezza di banda e un server magico che ha una quantità infinita di cicli di memoria e CPU, solo i websocket sono un'ottima scelta!

Csla fa quello che vuoi, gli oggetti business possono spostarsi tra client e server.
Andy,

Risposte:


50

Queste due tecnologie hanno uno scopo molto diverso.

  • REST è per le chiamate ordinarie a un'API, con il client come attore attivo dello scambio. Quando il client deve trovare le coordinate GPS di un indirizzo, il client avvia la chiamata all'API e attende fino a quando non riceve le coordinate, oppure si verifica un errore o non scade un timeout.

  • I socket Web sono per tutto ciò che deve fare le cose nel modo opposto. Ad esempio, quando utilizzo un sito Web Intranet che mi mostra in tempo reale i registri e le prestazioni di diversi server, il client può essere passivo e attendere fino a quando il server non gli invia un messaggio di registro o metriche delle prestazioni appena pubblicate.

La differenza è chiara: nel primo caso, il cliente decide quando necessita di un'informazione specifica; nel secondo caso, il cliente attende semplicemente di essere contattato e potrebbe non sapere quando sarebbe.

In qualche modo, entrambi sono intercambiabili: è possibile implementare socket Web quando non sono necessari (ovvero il client chiamerà il server tramite socket Web anziché effettuare una chiamata REST) ​​e è possibile utilizzare polling o polling lungo come sostituto di socket web (dato che questo è stato usato con successo per anni fino a quando i socket web sono diventati così popolari).

Ma la loro intercambiabilità ha un costo:

  • Quando si utilizza il polling o il polling lungo anziché i socket Web, si sta spesso sprecando larghezza di banda.

  • Quando si utilizzano i socket Web per fare ciò che può essere fatto tramite l'API Web, si mantengono aperte tutte le connessioni da tutti i client attivi, che potrebbero non essere ciò che si desidera realmente. Per un piccolo sito Web in cui prevedi di avere al massimo 5 clienti contemporaneamente, questo non è un problema. Per un servizio come Amazon AWS, questo non sarebbe facile da risolvere tecnicamente.

Non utilizzare i socket Web quando non ne hai bisogno. Per ottenere le coordinate GPS di un indirizzo, non ottengo nulla aprendo la connessione alle prese web, effettuando la chiamata, aspettando una risposta e chiudendo la connessione: REST soddisfa le mie esigenze per tali scenari.

  • Se ti ritrovi a controllare ripetutamente e frequentemente le informazioni tramite una chiamata REST a un servizio, questo potrebbe essere un buon segno che dovresti passare ai socket web. Allo stesso modo, Stack Overflow riduce l'utilizzo della larghezza di banda utilizzando i socket Web, poiché aiuta le persone a non perdere tempo a premere F5 sulla home page per vedere se hanno nuovi messaggi.

  • Se scopri che apri connessioni socket web, usale per effettuare una singola chiamata, quindi chiudile, o se le tue connessioni rimangono aperte ma il server sta inviando qualcosa al client solo su richiesta del client, passa a REST.

Inoltre, i socket Web hanno ancora un supporto limitato e non sono sempre facili da implementare. Mentre SignalR semplifica l'implementazione, ciò non significa che non avrai alcuna difficoltà ad implementarlo in altre lingue / contesti / ambienti. Con REST è facile: potrebbe essere una curlchiamata o una funzione simile disponibile in tutte le lingue tradizionali. Con i socket Web, non puoi essere sicuro di quanto tempo impiegherebbe un client a utilizzare [inserisci il nome di una lingua che non conosci ancora qui].

Ho usato i socket web in diversi progetti in .NET, Python e node.js.

  • In .NET, non è stato troppo difficile, ma ho ancora trascorso alcuni giorni cercando di capire alcuni problemi criptici, come la connessione interrotta non appena viene aperta. (Questo era prima di SignalR; non ho mai provato SignalR). Ho anche usato WCF in modalità socket web, che non era neanche un problema (ma credo che WCF abbia sempre dei problemi).

  • In node.js, questo era fattibile, ma ho dovuto cambiare due volte le librerie fino a quando non ho trovato una che funziona. Credo di aver trascorso almeno una settimana a provare a creare un socket Web Hello World.

  • In Python, ho provato una volta, ho trascorso due o tre giorni e ho abbandonato. Non ha mai funzionato

Confronta questo con REST: gli unici problemi che si possono incontrare con un nuovo linguaggio / framework sono sapere come inviare i file o ricevere una risposta binaria molto grande. Ricordo di aver trascorso alcune ore alla ricerca di soluzioni per alcune lingue. Tuttavia, poche ore per un caso speciale non sono nulla in confronto a giorni o settimane per un semplice Hello World.


2
Ho valutato la tua risposta, MainMa, come l'ho trovata interessante / utile. C'è un punto che non capisco però. Dici che un numero limitato di client è OK per gestire i socket web (ad esempio, al massimo 5 contemporaneamente). Quindi dici che StackOverflow utilizza i socket Web nella loro homepage. Come gestiscono un numero così elevato di utenti? Lo chiedo perché sto provando più di 20 connessioni SignalR e trovo che i ritardi dei messaggi iniziano lentamente ad aumentare, prima che tutto si rompa (tutto non risponde).
gnychis,

1
@gnychis: ci sono molte soluzioni, ma molte sono più legate all'infrastruttura stessa (questo è serverfault.com ). In generale, getta più hardware e dividi gli utenti tra i domini, in modo che alcune connessioni siano gestite da sockets1.example.com, altre da sockets2.example.com, ecc. Abbastanza efficaci ma anche piuttosto costose in termini di hardware e larghezza di banda.
Arseni Mourzenko,

3
Questa risposta è eccellente, ma vorrei restringere la domanda originale. Se un'app richiede una connessione a websocket continua, perché non utilizzare i websocket al posto di un'API REST? Poiché un websocket è aperto, forse dovrebbe essere pienamente utilizzato.
HappyNomad,

Ho appena trovato una risposta alla mia domanda.
HappyNomad,

1

Solo i miei 2 centesimi ...

Penso che non riguardi davvero le prestazioni o altro. Riguarda gli standard. REST è uno standard e IMHO presenta i seguenti vantaggi:

  • Le richieste HTTP sono semplici da usare. Tutti possono utilizzare rapidamente un'API REST. Diamine, puoi persino aprire il browser e digitare un URL per vedere i dati, quanto più interattivo puoi essere?
  • (Quasi) qualsiasi linguaggio di programmazione può usarlo. È una specie di interfaccia universale. L'interfaccia con SignalR di un linguaggio esotico sembra meno ovvia.
  • Ha un buon supporto per gli strumenti, come http://petstore.swagger.wordnik.com/
  • È una bella "interfaccia" per il debug. Puoi facilmente monitorare i messaggi in entrata e in uscita direttamente nel browser, vedere i dati, ecc. Con i websocket e le librerie personalizzate, non è così ovvio, devi registrare esplicitamente tutto.

1
Mentre fai alcuni punti positivi sul fatto che le API REST sono un po 'più semplici e probabilmente hanno strumenti migliori, questa risposta dice alcune cose che non sono vere. REST non è uno standard , mentre WebSocket lo è .
StriplingWarrior il

1
Immagino sia stata una formulazione scadente da parte mia. Ciò che intendevo con "standard" è essere banale, ampiamente utilizzato, il modo predefinito di fare le cose ... e non "essere uno standard RFC".
Dagnelies,

Buon chiarimento E, tra l'altro, Chrome ti consente almeno di vedere il traffico WebSocket nei suoi strumenti di sviluppo. Immagino che probabilmente lo facciano anche gli altri browser.
StriplingWarrior il
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.