Domanda

Se esiste una risorsa REST che voglio monitorare per cambiamenti o modifiche da altri client, qual è il modo migliore (e più RESTful) di farlo?

Un'idea che ho avuto per farlo è fornire risorse specifiche che manterranno aperta la connessione piuttosto che restituire immediatamente se la risorsa non esiste (ancora). Ad esempio, data la risorsa:

/game/17/playerToMove

a " OTTIENI " su questa risorsa potrebbe dirmi che è il turno del mio avversario di muoversi. Invece di sondare continuamente questa risorsa per scoprire quando è il mio turno di spostarmi, potrei notare il numero di mossa (diciamo 5) e provare a recuperare la mossa successiva:

/game/17/move/5

In un "normale" Modello REST, sembra che una richiesta GET per questo URL restituisca un errore 404 (non trovato). Tuttavia, se invece, il server ha mantenuto la connessione aperta fino a quando il mio avversario ha giocato la sua mossa, ovvero:

PUT /game/17/move/5

allora il server potrebbe restituire i contenuti che il mio avversario ha messo in quella risorsa. Ciò mi fornirebbe sia i dati di cui ho bisogno, sia una sorta di notifica per quando il mio avversario si è mosso senza richiedere il polling.

Questo tipo di schema è RESTful? O viola una sorta di principio REST?

È stato utile?

Soluzione

La soluzione proposta sembra polling lungo , che potrebbe funzionare davvero bene.

Dovresti richiedere / game / 17 / move / 5 e il server non invierà alcun dato fino a quando lo spostamento 5 non sarà completato. Se la connessione si interrompe o si ottiene un timeout, è sufficiente riconnettersi fino a quando non si ottiene una risposta valida.

Il vantaggio di questo è che è molto veloce: non appena il server ha nuovi dati, il client li riceverà. È anche resistente alle connessioni interrotte e funziona se il client viene disconnesso per un po '(potresti richiedere / game / 17 / move / 5 un'ora dopo che è stato spostato e ottenere i dati istantaneamente, quindi spostare su move / 6 / e così via)

Il problema con il polling lungo è ogni "poll" " lega un thread del server, che rompe rapidamente i server come Apache (poiché si esaurisce il thread di lavoro, quindi non può accettare altre richieste). È necessario un server web specializzato per soddisfare le richieste di polling lungo. Il modulo Python twisted (un "motore di rete guidato dagli eventi") è ottimo per questo, ma è più lavoro che polling regolare ..

In risposta al tuo commento su Jetty / Tomcat, non ho alcuna esperienza con Java, ma sembra che entrambi utilizzino un sistema di pool di thread di lavoro simile ad Apache, quindi avrà lo stesso problema. Ho trovato questo post che sembra risolve esattamente questo problema (per Tomcat)

Altri suggerimenti

Ho trovato questo articolo che propone una nuova intestazione HTTP, " When-Modified-After " ;, che essenzialmente fa la stessa cosa: il server attende e mantiene aperta la connessione fino alla modifica della risorsa.

Preferisco un approccio basato sulla versione piuttosto che un approccio basato sul timestamp, dal momento che è meno incline alle condizioni di gara e ti dà un po 'più informazioni su ciò che stai recuperando. Qualche idea su questo approccio?

Suggerirei un 404, se il client previsto è un browser Web, poiché mantenere aperta la connessione può bloccare attivamente le richieste del browser nel client allo stesso dominio. Spetta al cliente la frequenza con cui effettuare il polling.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top