Come risparmiare durante la collaborazione in tempo reale


10

Voglio che più utenti modifichino lo stesso documento. Il problema che sto affrontando è quando un nuovo utente si unisce, potrebbe vedere un documento obsoleto. Come posso assicurarmi che i nuovi utenti ricevano le modifiche più recenti?

Alcune soluzioni a cui ho pensato:

  • Risparmia su ogni modifica. Non mi piace questa soluzione perché rallenterà le cose sull'interfaccia utente e caricherà su db.

  • Quando un nuovo utente si unisce, attiva il salvataggio su tutti gli altri client. Dopo aver salvato altri client, caricare il documento. Con ciò può esserci ancora un'incoerenza.

Qualsiasi altro suggerimento sarebbe utile.

AGGIORNAMENTO: Dopo aver esaminato la soluzione suggerita, l'API di Google Realtime, ho scoperto che:

  1. Gli utenti della tua app devono avere Google Drive e darti accesso al loro disco . Nella migliore delle ipotesi, ciò potrebbe presentare un flusso di interfaccia utente imbarazzante o impedire agli utenti che non dispongono di Google Drive di utilizzare la funzione in tempo reale.

  2. Tutte le impostazioni di condivisione eseguite al tuo fianco devono essere replicate per il documento Google.

AGGIORNAMENTO 2: Per raggiungere l'obiettivo, sono andato con Firebase di Google


Perché c'è una differenza tra un nuovo utente e utenti già attivi che modificano / visualizzano lo stesso documento?
Andy,

@Andy Quello che sto facendo è trasmettere tramite socket tutti i cambiamenti che gli utenti fanno. Queste modifiche aggiornano l'interfaccia utente per gli utenti che hanno i browser aperti ma non vengono immediatamente salvati nel database. Quindi ho una situazione, quando un nuovo utente si unisce, carica il documento dal database e non vede tutte le modifiche recenti che non sono state ancora salvate.
dev.e.loper

1
se stai già inviando modifiche e vuoi lasciare lo stesso comportamento come è ora, puoi chiedere a uno dei client di inviare l'ultima vista al nuovo client o puoi avere un client virtuale sul server, che riceve tutte le modifiche e quando i nuovi client si collegano vederlo.
Dainius,

Risposte:


14

Google Drive

Se stai provando a creare la tua versione di documenti Google, ti suggerisco di dare un'occhiata all'API in tempo reale di Google . Google ha recentemente rilasciato questo con l'intento di consentire ad altri sviluppatori di utilizzare gli stessi strumenti che hanno fatto per consentire la collaborazione in tempo reale. Ciò ti consentirebbe di risparmiare tempo nello sviluppo e di ottenere prima un prodotto funzionante.

È possibile prendere facilmente i dati presenti nel documento e trasferirli nel database a intervalli regolari oppure fare in modo che il database stesso sia un "partecipante" dello scambio, semplicemente ascoltando e registrando tutte le modifiche. Inoltre, consente a un utente di definire le proprie strutture di dati che sono quindi utilizzabili nell'API in tempo reale, quindi sei libero di estenderlo come ritieni opportuno.

Non Google Drive

Quindi, secondo la tua ricerca, Google Drive non è un'opzione. Va bene, ma sarà più duro e forse non funzionerà altrettanto bene, a seconda di quanto ci metti dentro.

Ecco una strategia generale I vorrei utilizzare per realizzare questo problema:

  1. Avere il server come multiplexer di comunicazione. Ogni persona parla al server e il server invia tali informazioni a tutti gli altri. In questo modo il server ha sempre la vista più aggiornata del documento.

  2. Trova un algoritmo / modulo di terze parti per la risoluzione dei conflitti. La risoluzione dei conflitti è dura ed è qualcosa che non è ancora perfetto. Farlo da solo potrebbe facilmente aumentare la portata del progetto in modo che sia troppo grande. Se non puoi utilizzare un algoritmo di terze parti, ti suggerirei di consentire a un solo utente di modificare un'area di un tempo, in modo che l'utente debba ottenere un blocco prima di modificare un'area o rischi di distruggere un altro lavoro degli utenti, che diventerà molto vecchio, molto veloce.

  3. Quando un nuovo utente si unisce, dai loro il documento più recente e avvia automaticamente lo streaming dei comandi su di loro. Il server ha la vista più recente e può quindi essere visualizzato automaticamente.

  4. Eseguire il backup nel database a determinati intervalli. Decidi con quale frequenza desideri eseguire il backup (ogni 5 minuti o forse ogni 50 modifiche). Ciò ti consente di mantenere il backup desiderato.

I problemi: questa non è una soluzione perfetta, quindi ecco alcuni problemi che potresti incontrare.

  1. Il throughput del server potrebbe compromettere le prestazioni

  2. Troppe persone che leggono / scrivono potrebbero sovraccaricare il server

  3. Le persone potrebbero non essere sincronizzate se un messaggio viene perso, quindi potresti voler assicurarti di sincronizzare in punti regolari. Questo significa inviare di nuovo l'intero messaggio, che può essere costoso, ma altrimenti le persone potrebbero non avere lo stesso documento e non conoscerlo.


Sì, le modifiche vengono trasmesse a tutti i client e hanno la loro (eventualmente la stessa) versione sul browser. Sembra che tu stia dicendo che, l'aggiornamento del documento su ogni azione, è una strada da percorrere?
dev.e.loper il

O almeno disporre di intervalli regolari di "sincronizzazione" in cui lo stato corrente del documento viene trasmesso in background per assicurarsi che tutti siano sulla stessa pagina. Quanto spesso dipenderà dalla velocità con cui le persone cambieranno il documento. In questo modo hai già un metodo consolidato per l'invio a nuove persone, oltre alla possibilità di assicurarti che non diverga mai troppo.
Appunto

1
+1. Non rendere la vita difficile. Google lo fa bene senza dover reinventare la ruota.
Neil,

Google Realtime salva su Google Drive? Voglio salvare nel mio database, non in Google Drive.
dev.e.loper il

@ dev.e.loper ha aggiunto alcune informazioni in merito alla risposta per te.
Ampt

3

Consiglierei 1 copia persistente del documento sul server. Quando un client si connette al server, si emette un UPDATEcomando (i) a quel client con tutte le modifiche.

Aggiorna WorkFlow

L'utente provoca l'attivazione della modifica -> Il client invia UPDATEal server -> Il server inviaUPDATE ai client

Trigger praticabili

  1. L'utente fa clic su Salva
  2. L'utente completa un'attività specifica
    • Termina la modifica di una cella
    • Termina la modifica di una frase / paragrafo / riga
  3. L'utente fa clic su Annulla
  4. L'utente preme il tasto Invio
  5. L'utente digita una chiave (salva su ogni modifica)

Implementazione dell'aggiornamento

Suggerirei di essere in grado di ricreare il documento con una serie di UPDATEcomandi in modo che il server memorizzi ogni AGGIORNAMENTO e quando un nuovo client si connette al client può essere inviato la serie di aggiornamenti e esso stesso può ricreare il documento da visualizzare l'utente. Inoltre, è possibile in alternativa disporre di un SAVEcomando separato e UPDATE può essere una modifica temporanea che può essere utilizzata per le UNDOrichieste e che SAVE effettivamente lo memorizzi per essere riaperto se il server è chiuso o tutti i client si disconnettono.


2
Che dire della risoluzione dei conflitti? Che cosa succede se due persone modificano la stessa area di testo contemporaneamente? Inoltre, questo sembra caricare un carico sul DB, cosa che OP stava cercando di evitare. Potrebbe essere fattibile per quello che gli serve però.
Apporto del

@Ampt Ho creato un foglio di calcolo utilizzando questo modello e, per i conflitti, ogni attività specifica in fase di aggiornamento è stata completamente sostituita dalla versione più recente. Quindi l'ultima persona a terminare la modifica di una cella sostituirà completamente quella precedentemente aggiornata senza alcuna fusione.
Korey Hinton,

1
Quindi una frase ne sovrascriverebbe un'altra se questo fosse, diciamo, un documento verbale?
Ampt

@Ampt sì, in alternativa potresti implementare un modo per bloccare ciò su cui si sta lavorando, ma ho preso la strada facile.
Korey Hinton,

3

1) Dai un'occhiata a Knockout.js

Segue un modello MVVM e invierà automaticamente le notifiche alla vista in base alle modifiche al modello. Ad esempio, guarda il loro array osservabile per fornire un po 'più di informazioni su come lo fanno.

2) Combinalo con SignalR e ora dovresti avere la possibilità di inviare notifiche ad altri utenti che lavorano al documento. Dal loro sito:

SignalR fornisce anche un'API di alto livello molto semplice per eseguire RPC da server a client (chiamare le funzioni JavaScript nei browser dei client dal codice .NET lato server) nell'applicazione ASP.NET, oltre ad aggiungere hook utili per la gestione delle connessioni , ad es. eventi di connessione / disconnessione, raggruppamento di connessioni, autorizzazione.

Quindi sarà necessario disporre di alcuni hook a livello di modello in Knockout.js per effettuare alcune chiamate SignalR ogni volta che si verifica una modifica. Gli altri client riceveranno l'avviso da SignalR e quindi attiveranno una modifica corrispondente nella loro copia del Modello, che tornerà alla loro Vista.

È una combinazione interessante dei due framework e dovresti essere in grado di cercare e raccogliere più informazioni per gestire i dettagli.

Ad esempio, questo esempio di codeproject si rivolge specificamente a quello Co Working UIs and Continuous Clientsche sembra essere esattamente ciò che stai cercando di fare.

Le applicazioni web della nuova era potrebbero dover offrire esperienze per gli utenti della nuova era - e dovrebbero gestire correttamente gli scenari di collaborazione e client continui. Ciò implica garantire che l'interfaccia utente si sincronizzi correttamente tra i dispositivi e tra gli utenti per garantire che lo stato dell'applicazione e l'interfaccia utente siano mantenuti "così come sono".

Questo post sul blog sembra essere un punto di ingresso in una serie di post sul blog che parlano dell'uso dei due pacchetti e sono in contrasto con un approccio ASP.NET tradizionale. Può fornire alcuni punti da considerare durante la progettazione del sito.

Questo post sul blog sembra essere un po 'più semplice e fornisce le basi per combinare i due pacchetti.

Divulgazione: non sono affiliato con nessuno dei link sopra riportati, né ho davvero scavato nel loro contenuto per vedere quanto sia corretto o corretto.


2

La soluzione è Operational Transformation (OT). Se non ne hai sentito parlare, OT è una classe di algoritmi che fanno concorrenza in tempo reale su più siti. OT è come un idiota in tempo reale. Funziona con qualsiasi quantità di ritardo (da zero a una vacanza estesa). Consente agli utenti di apportare modifiche simultanee in tempo reale con larghezza di banda ridotta. OT ti dà l'eventuale coerenza tra più utenti senza tentativi, senza errori e senza che i dati vengano sovrascritti.

Ma implementare OT è un compito difficile e richiede tempo. Quindi potresti voler usare una libreria esterna come http://sharejs.org/ .


1
L'API di Google Realtime sta facendo OT youtu.be/hv14PTbkIs0?t=14m20s Lo fanno sia su client che su server. Non sono riuscito a ottenere una risposta chiara dalla lettura dei documenti di ShareJS ma suppongo che ShareJS esegua OT sia su client che su server?
dev.e.loper

1

Dipende principalmente dal tipo di documenti e da come gli utenti collaborano.

Tuttavia, vorrei:

  1. consenti a tutti i client di inviare al server modifiche non salvate di tanto in tanto (dipende da come gli utenti lavorano con i documenti).
  2. il server memorizza i delta nella sessione dell'utente (anche per un client fat hai bisogno di qualcosa come una sessione)
  3. altri client che modificano / visualizzano lo stesso documento ottengono tali modifiche temporanee o almeno un suggerimento che potrebbe esserci.

vantaggi:

  • nessun aggiornamento DB a meno che qualcuno non faccia clic su "Salva"
  • backup per il caso in cui il client si arresta in modo anomalo (per il periodo della sessione)
  • il tuo server decide come e quali dati inoltrare a quale client (ad es. puoi avviare la funzione con una nota e successivamente implementare un'unione e un evidenziatore più sofisticati)

svantaggi:

  • non "in tempo reale", ad esempio invii ogni 30 secondi, ma in quel momento qualcuno digita 3 frasi.
  • più traffico di rete, a seconda dei documenti e della collaborazione
  • possibilmente sessioni di grandi dimensioni
  • probabilmente un elevato sforzo di calcolo se molti utenti collaborano e apportano molte modifiche

1

In sostanza, quello che stai chiedendo è come gestire lo stato mutevole condiviso. Il risparmio è la parte facile; ma come gestisci più persone che modificano la stessa cosa contemporaneamente? Desideri che tutti gli utenti visualizzino lo stesso documento mentre sincronizzano le modifiche simultanee, il tutto in tempo reale.

Come probabilmente avrai raccolto, è un problema difficile! Esistono alcune soluzioni pragmatiche:

  1. Modifica i requisiti dell'applicazione per non consentire una vera modifica simultanea. Le modifiche possono essere unite come con i sistemi di controllo del codice sorgente, con i risultati trasmessi a ciascun client. Potresti costruirlo tu stesso ma sarebbe un'esperienza utente più scadente.
  2. Esternalizzare la sincronizzazione delle mutazioni di stato in una soluzione open source che si integra con la tecnologia esistente. ShareDB è l'attuale leader in questo spazio. Si basa sulla trasformazione operativa e viene utilizzato in almeno un sistema di produzione. Questo risolverà il problema di salvataggio di cui ti preoccupi ma non ti aiuterà con nessuna delle funzionalità UX aggiuntive obbligatorie per qualsiasi applicazione collaborativa.
  3. Usa una piattaforma standard come Convergence (dichiarazione di non responsabilità: sono un fondatore) per gestire tutte le cose difficili per te. Avrai anche strumenti aggiuntivi per la collaborazione in tempo reale come il tracciamento del cursore / mouse, le selezioni e la chat per creare rapidamente un'esperienza di collaborazione superiore. Vedi questa domanda per una buona carrellata di tutti gli strumenti esistenti.
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.