2010-11-05 13 views
8

Sto solo cercando idee/suggerimenti qui; Non sto chiedendo una soluzione completa (anche se ne hai uno, sarei felice di vederlo)Trova ciò che è stato modificato e carica solo le modifiche

Sto cercando un modo per caricare solo le modifiche al testo. Molto probabilmente verrà utilizzato come applicazione basata su cloud in esecuzione su jQuery e HTML, con un server PHP che esegue il back-end.

Per esempio, se ho un testo come

asdfghjklasdfghjkl 

E lo cambio a

asdfghjklXasdfghjkl 

Io non voglio avere a caricare il tutto (il testo può ottenere abbastanza grande)

per esempio, qualcosa come 8,X inviato al server potrebbe significare: add an X to the 8th position

O D8,3 potrebbe significare: go to position 8 and delete the previous 3 terms

Tuttavia, se una singola richiesta è danneggiato in rotta verso il server, l'intero documento potrebbe essere danneggiato dal momento che le posizioni sarebbero cambiate. Un semplice hash potrebbe rilevare la corruzione, ma come procedere nel recupero dalla corruzione? Il cliente avrà tutti i dati, ma i dati sono probabilmente molto grandi, ed è improbabile che sia possibile caricarli.

Quindi grazie per aver letto tutto questo. Ecco un breve riassunto di ciò che ha bisogno di suggerimenti

  • Modifica/modifica di rilevamento
  • metodo per comunicare i cambiamenti
  • recupero dalla corruzione
  • Qualsiasi altra cosa che ha bisogno di miglioramento
+2

domanda interessante .. dovrete affrontare problemi di concorrenza per. Forse inviando sequenze di tasti o memorizzando le modifiche per sputare sul server a intervalli di tempo fissi con un numero di revisione da controllare. Un problema è che se il testo è (molto) grande, potresti avere anche problemi nel gestirlo sul client. – Hamish

+0

@Hamish: Per risolvere il problema, avrò a jQuery ottenere le dimensioni dello schermo del dispositivo e il server invierà un numero sufficiente di testo per riempire 3 volte quello schermo. Quindi, mentre l'utente scorre, il resto del testo può essere trasmesso in streaming. Mi piace il tuo suggerimento sul tempo/le revisioni. Sarò sicuro di tenerlo a mente. – Kranu

+0

a meno che * gli * schermi * abbiano una risoluzione gigantesca dei pixel che nessun altro ha, 3 schermate piene di testo non sono così tanti dati da gestire. Immagino circa 50-100kb, dov'è il problema di mandare tutto al server? – joni

risposta

4

C'è già una forma accettata per la trasmissione di questo tipo di informazioni "differenze". Si chiama Unified Diff.

google-diff-match-patch fornisce implementazioni in Java, JavaScript, C++, C#, Lua e Python.

Si dovrebbe essere in grado di mantenere il "testo originale" e il "testo modificato" nelle variabili sul client, quindi generare il diff in javascript (tramite diff-match-patch), inviarlo al server, lungo con un hash, e ri-costruirlo (usando diff-match-patch o il programma unix "patch") sul server.

Si potrebbe anche prendere in considerazione l'inclusione di una "versione" (o una data di modifica) quando si invia il testo originale al client in primo luogo. Quindi includere la stessa versione (o data) nella "richiesta diff" che il client invia al server. Verificare la versione sul server prima di applicare il diff, in modo da essere sicuri che la copia del testo del server non sia stata divergita dalla copia del client durante la modifica. (ovviamente, affinché funzioni, è necessario aggiornare il numero di versione sul server ogni volta che la copia master viene aggiornata).

+0

Wow Google ha in corso alcuni progetti interessanti, ma non sospetto che abbiano fatto ciò che sto cercando di fare. Sfortunatamente, non sono su un computer in piena regola in questo momento, ma controllerò il progetto non appena possibile. – Kranu

1

Hai un approccio davvero interessante. Ma se i file di testo sono davvero così grandi che avrebbe bisogno di troppo tempo per caricarli ogni volta, perché hai inviato l'intera cosa al cliente? Il client deve davvero ricevere l'intero file di testo 5mb? Non sarebbe possibile mandargli solo ciò di cui ha bisogno?

In ogni caso, per la tua domanda: La prima cosa che mi viene in mente quando sento "file di testo di grandi dimensioni" e il rilevamento delle modifiche è diff. Per l'algoritmo, leggi here. Questo potrebbe essere un approccio per commettere le modifiche e specifica un formato per questo. Dovresti semplicemente ricostruire diff (o parte di esso) in javascript. Questo non sarà facile, ma possibile, come immagino. Se l'algoritmo non ti aiuta, almeno la definizione del formato di file diff.

Per il problema di corruzione: non devi temere che la tua data venga corrotta lungo il percorso, perché il protocollo TCP, su cui è basato HTTP, sembra che tutto arrivi senza essere danneggiato. Quello che dovresti temere è la reimpostazione della connessione. Potresti fare qualcosa come una stretta di mano? Quando il client invia un aggiornamento al server, il server applica le modifiche e mantiene una versione precedente del file. Per garantire che il client abbia ricevuto la ratifica dal server che la modifica è andata bene (è qui che si verifica il reset del conneciton), il client invia un'altra richiesta Ajax al server.Se questo non arriva al server entro il tempo definito, il file viene ripristinato sul lato server.

Un'altra cosa: non so se javascript piace a gestire tali file/dati giganteschi ...

+0

Ho intenzione di inviare solo ciò che l'utente può vedere sullo schermo. Ad esempio, Google Reader carica solo un paio di articoli quando lo apri, ma quando fai scorrere gli articoli, ne carichi di più. Se ci sono troppi dati, posso rimuoverlo una volta che perde la vista. Grazie per il tuo suggerimento di utilizzare diff. Ne darò uno sguardo dopo. Anche se non riesco a portarlo su Javascript. Sono sicuro che l'algoritmo mi sarà utile. – Kranu

1

Questo sembra un problema che i sistemi di controllo delle versioni (CVS, SVN, Git, Bazaar) risolvono già molto bene.

Sono tutti abbastanza facili da configurare su un server e puoi comunicare con loro tramite PHP.

Dopo la configurazione, si otterrebbe gratuitamente: controllo delle versioni, log, rollback, gestione delle modifiche simultanee, la sintassi corretta diff, tagging, rami ...

Non si otterrebbe il 'invia solo il aggiorna la funzionalità che hai richiesto. Non sono sicuro di quanto sia importante per te. I testi puri sono davvero molto economici da inviare per quanto riguarda la larghezza di banda.

Personalmente, probabilmente farei un compromesso simile a quello che fanno i wiki. Suddividi l'intero testo in parti più piccole semanticamente coerenti (capitoli o anche paragrafi), determina sul lato client solo quali blocchi sono stati modificati (senza scendere al livello del personaggio) e invia quelli.

Il server può quindi rispondere con un diff, generato dal proprio sistema di controllo delle versioni, che è qualcosa che fanno in modo molto efficiente. Se si desidera consentire modifiche simultanee, è possibile che si verifichino casi in cui gli editor devono comunque eseguire le unioni manuali.

Un altro suggerimento generico potrebbe essere quello di vedere cosa ha fatto Google con Wave. Devo rimanere generale qui, perché non l'ho studiato in dettaglio, ma mi sembra di ricordare che ci sono stati alcuni articoli su come hanno risolto il problema di editing simultaneo in tempo reale, che sembra essere esattamente cosa ti piacerebbe fare.

In sintesi, credo che il problema che si intende affrontare sia tutt'altro che banale, ci sono strumenti che affrontano già molti dei problemi associati, e personalmente comprometterei e riformerei l'approccio a favore di molto meno carico di lavoro.

Problemi correlati