Comment économiser pendant la collaboration en temps réel

10

Je souhaite que plusieurs utilisateurs modifient le même document. Le problème auquel je suis confronté est lorsqu'un nouvel utilisateur rejoint, il peut voir un document obsolète. Comment puis-je m'assurer que les nouveaux utilisateurs reçoivent les modifications les plus récentes?

Quelques solutions auxquelles j'ai pensé:

  • Économisez sur chaque changement. Je n'aime pas cette solution car elle ralentira les choses sur l'interface utilisateur et mettra la charge sur db.

  • Lorsqu'un nouvel utilisateur rejoint, déclenchez la sauvegarde sur tous les autres clients. Une fois les autres clients enregistrés, chargez le document. Avec cela, il peut encore y avoir des incohérences.

Toute autre suggestion serait utile.

MISE À JOUR: Après avoir examiné la solution suggérée, l'API Google Realtime, j'ai découvert que:

  1. Les utilisateurs de votre application doivent disposer de Google Drive et vous donner accès à leur lecteur . Cela pourrait au mieux présenter un flux d'interface maladroit ou empêcher les utilisateurs qui n'ont pas Google Drive d'utiliser la fonctionnalité en temps réel.

  2. Tous les paramètres de partage qui se font de votre côté doivent être répliqués pour le document Google.

MISE À JOUR 2: Pour atteindre l'objectif, je suis allé avec Firebase de Google

développeur
la source
Pourquoi y a-t-il une différence entre un nouvel utilisateur et des utilisateurs déjà actifs modifiant / visualisant le même document?
Andy
@Andy Ce que je fais actuellement, c'est de diffuser via des sockets toutes les modifications apportées par les utilisateurs. Ces modifications mettent à jour l'interface utilisateur pour les utilisateurs dont le navigateur est ouvert, mais ils ne sont pas instantanément enregistrés dans la base de données. J'ai donc une situation, lorsqu'un nouvel utilisateur rejoint, il charge le document à partir de la base de données et il ne voit pas toutes les modifications récentes qui n'ont pas encore été enregistrées.
dev.e.loper
1
si vous envoyez déjà des modifications et souhaitez laisser le même comportement tel qu'il est maintenant, vous pouvez demander à l'un des clients d'envoyer la dernière vue au nouveau client ou vous pouvez avoir un client virtuel sur le serveur, qui obtient toutes les modifications et lorsque le nouveau client rejoint envoie la dernière voir.
Dainius

Réponses:

14

Google Drive

Si vous essayez de créer votre propre version de Google Documents, je vous suggère de jeter un œil à l' API Google Realtime . Google a récemment publié cela dans le but de permettre à d'autres développeurs d'utiliser les mêmes outils qu'ils ont utilisés pour permettre une collaboration en temps réel. Cela vous permettrait de gagner du temps sur votre développement et d'obtenir un produit fonctionnel plus tôt.

Vous pouvez facilement prendre les données contenues dans le document et les insérer dans votre base de données à intervalles réguliers, ou faire en sorte que la base de données elle-même soit un «participant» de l'échange, simplement en écoutant et en enregistrant toutes les modifications. Il permet également à un utilisateur de définir ses propres structures de données qui sont ensuite utilisables dans l'API en temps réel, vous êtes donc libre de l'étendre comme bon vous semble.

Non-Google Drive

Donc, selon vos recherches, Google Drive n'est pas une option. C'est bien, mais ça va être plus difficile et peut-être ne pas fonctionner aussi bien, selon la quantité que vous y mettez.

Voici une stratégie générale que j'utiliserais pour résoudre ce problème:

  1. Demandez au serveur d'être le multiplexeur de communication. Chaque personne parle au serveur et le serveur envoie ces informations à tout le monde. De cette façon, le serveur a toujours la vue la plus récente du document.

  2. Trouvez un algorithme / module tiers pour la résolution des conflits. La résolution des conflits est difficile et n'est toujours pas parfaite. Faire cela seul pourrait facilement augmenter la portée du projet pour qu'il soit beaucoup trop important. Si vous ne pouvez pas utiliser un algorithme tiers, je vous suggère de n'autoriser qu'un seul utilisateur à modifier une zone de temps, de sorte que l'utilisateur doit obtenir un verrou avant de modifier une zone, ou vous risquez de détruire le travail d'un autre utilisateur, ce qui va devenir très vieux, très rapide.

  3. Lorsqu'un nouvel utilisateur se joint à lui, donnez-lui le document le plus récent et lancez automatiquement la diffusion des commandes vers lui. Le serveur a la vue la plus récente et peut donc la diffuser automatiquement.

  4. Sauvegarde dans la base de données à certains intervalles. Décidez de la fréquence à laquelle vous souhaitez sauvegarder (toutes les 5 minutes ou peut-être toutes les 50 modifications.) Cela vous permet de conserver la sauvegarde que vous souhaitez.

Problèmes: Ce n'est pas une solution parfaite, alors voici quelques problèmes auxquels vous pourriez être confrontés.

  1. Le débit du serveur pourrait réduire les performances

  2. Trop de personnes lisant / écrivant pourraient surcharger le serveur

  3. Les personnes peuvent se désynchroniser si un message est perdu, vous pouvez donc vous assurer de vous synchroniser à des moments réguliers. Cela signifie envoyer à nouveau tout le message, ce qui peut être coûteux, mais sinon les gens pourraient ne pas avoir le même document et ne pas le savoir.

Ampt
la source
Oui, les modifications sont diffusées à tous les clients et ils ont leur version (si tout va bien la même) sur le navigateur. On dirait que vous dites que la mise à jour du document sur chaque action est un chemin à parcourir?
dev.e.loper
Ou au moins avoir des délais de synchronisation réguliers où l'état actuel du document est transmis en arrière-plan pour s'assurer que tout le monde est sur la même page. La fréquence dépendra de la vitesse à laquelle les gens changeront le document. De cette façon, vous avez déjà une méthode établie pour envoyer de nouvelles personnes, ainsi que la possibilité de vous assurer qu'elle ne diverge pas trop.
Ampt
1
+1. Ne rendez pas la vie difficile. Google le fait bien sans avoir à réinventer la roue.
Neil
Google Realtime enregistre-t-il sur Google Drive? Je souhaite enregistrer dans ma base de données, pas dans Google Drive.
dev.e.loper
@ dev.e.loper a ajouté quelques informations à ce sujet à la réponse pour vous.
Ampt
3

Je recommanderais 1 copie persistante du document sur le serveur. Lorsqu'un client se connecte au serveur, vous émettez une ou plusieurs UPDATEcommandes à ce client avec toutes les modifications.

Mettre à jour WorkFlow

L'utilisateur provoque un changement de déclenchement -> Le client envoie UPDATEau serveur -> Le serveur envoie UPDATEaux clients

Déclencheurs viables

  1. L'utilisateur clique sur Enregistrer
  2. L'utilisateur termine une tâche spécifique
    • Termine l'édition d'une cellule
    • Termine la modification d'une phrase / d'un paragraphe / d'une ligne
  3. L'utilisateur clique sur Annuler
  4. L'utilisateur appuie sur la touche Retour
  5. L'utilisateur tape une clé (économisez à chaque changement)

Mettre à jour la mise en œuvre

Je suggérerais de pouvoir recréer le document avec une série de UPDATEcommandes pour que le serveur stocke chaque MISE À JOUR et lorsqu'un nouveau client se connecte, le client peut recevoir la série de mises à jour et lui-même peut recréer le document à afficher l'utilisateur. En outre, vous pouvez également avoir une SAVEcommande distincte et avoir UPDATE des modifications temporaires qui peuvent être utilisées pour les UNDOdemandes et avoir SAVE réellement le stocker pour être rouvert si le serveur est fermé ou tous les clients se déconnectent.

Korey Hinton
la source
2
Et la résolution des conflits? Que faire si deux personnes modifient la même zone de texte en même temps? En outre, cela semble mettre une charge sur la base de données, ce que OP cherchait à éviter. Cela pourrait être viable pour ce dont il a besoin.
Ampt
@Ampt J'ai créé une feuille de calcul en utilisant ce modèle, et pour les conflits, chaque tâche spécifique en cours de mise à jour a été complètement remplacée par la version la plus récente. Ainsi, la dernière personne à terminer la modification d'une cellule remplacera complètement la cellule précédemment mise à jour sans fusion.
Korey Hinton le
1
Donc, une phrase en remplacerait une autre s'il s'agissait, disons, d'un document Word?
Ampt
@Ampt oui, vous pouvez également implémenter un moyen de verrouiller ce qui est en cours de traitement, mais j'ai choisi la voie la plus simple.
Korey Hinton le
3

1) Jetez un œil à Knockout.js

Il suit un modèle MVVM et envoie automatiquement des notifications à la vue en fonction des modifications apportées au modèle. Par exemple, regardez dans leur tableau observable pour fournir un peu plus d'informations sur la façon dont ils le font.

2) Mélangez cela avec SignalR et vous devriez maintenant avoir la possibilité d'envoyer des notifications aux autres utilisateurs travaillant sur le document. Depuis leur site:

SignalR fournit également une API de haut niveau très simple pour faire du serveur au client RPC (appeler les fonctions JavaScript dans les navigateurs de vos clients à partir du code .NET côté serveur) dans votre application ASP.NET, ainsi que l'ajout de crochets utiles pour la gestion des connexions , par exemple, connecter / déconnecter des événements, regrouper des connexions, autorisation.

Vous devrez donc avoir des crochets au niveau de votre modèle dans Knockout.js pour effectuer des appels SignalR chaque fois qu'un changement se produit. Les autres clients recevront la notification de SignalR, puis déclencheront un changement correspondant dans leur copie du modèle, qui repoussera à leur vue.

C'est une combinaison intéressante des deux cadres, et vous devriez être en mesure de rechercher et de recueillir plus d'informations pour gérer les détails.

Par exemple, cet exemple de projet de code traite spécifiquement de Co Working UIs and Continuous Clientsce qui semble être exactement ce que vous essayez de faire.

Les applications Web New Age peuvent devoir offrir des expériences utilisateur New Age - et doivent gérer correctement les scénarios de collaboration et de clients continus. Cela implique de s'assurer que l'interface utilisateur se synchronise correctement elle-même entre les appareils et entre les utilisateurs pour garantir que l'état de l'application et de l'interface utilisateur est maintenu "tel quel".

Ce billet de blog semble être un point d'entrée dans une série de billets de blog discutant de l'utilisation des deux packages et contrastant avec une approche ASP.NET traditionnelle. Peut fournir quelques points à considérer lors de la conception de votre site.

Ce billet de blog semble être un peu plus basique et fournit les bases pour combiner les deux packages.

Divulgation: je ne suis affilié à aucun des liens ci-dessus et je n'ai pas vraiment fouillé dans leur contenu pour voir à quel point il est sain ou correct.


la source
2

La solution est la transformation opérationnelle (OT). Si vous n'en avez pas entendu parler, OT est une classe d'algorithmes qui utilisent la simultanéité multisite en temps réel. OT est comme git en temps réel. Il fonctionne avec n'importe quel décalage (de zéro à des vacances prolongées). Il permet aux utilisateurs d'effectuer des modifications simultanées en direct avec une faible bande passante. OT vous offre une cohérence éventuelle entre plusieurs utilisateurs sans nouvelles tentatives, sans erreurs et sans que les données soient écrasées.

Mais la mise en œuvre de l'OT est une tâche difficile et longue. Vous voudrez donc peut-être utiliser une bibliothèque externe comme http://sharejs.org/ .

un J_
la source
1
L'API Google Realtime fait OT youtu.be/hv14PTbkIs0?t=14m20s Ils le font à la fois sur le client et sur le serveur. Je n'ai pas pu obtenir de réponse claire en lisant les documents ShareJS, mais je suppose que ShareJS fait OT sur le client et le serveur?
dev.e.loper
1

Cela dépend principalement du type de vos documents et de la façon dont vos utilisateurs collaborent.

Cependant, je voudrais:

  1. laissez tous les clients envoyer des modifications non enregistrées au serveur de temps en temps (cela dépend de la façon dont les utilisateurs travaillent avec les documents).
  2. le serveur stocke les deltas dans la session de l'utilisateur (même pour un gros client, vous avez besoin de quelque chose comme une session)
  3. d'autres clients éditant / visualisant le même document obtiennent ces modifications temporaires ou au moins une indication qu'il pourrait y en avoir.

Avantages:

  • aucune mise à jour de la base de données sauf si quelqu'un clique sur "enregistrer"
  • sauvegarde pour le cas où le client plante (pour la période de session)
  • votre serveur décide comment et quelles données transmettre à quel client (par exemple, vous pouvez démarrer la fonctionnalité avec juste une note et ensuite implémenter une fusion et une mise en surbrillance plus sophistiquées)

Désavantages:

  • pas «en temps réel» - par exemple, vous envoyez toutes les 30 secondes, mais quelqu'un tape 3 phrases pendant ce temps.
  • plus de trafic réseau - en fonction de vos documents et de votre collaboration
  • éventuellement de grandes sessions
  • effort de calcul éventuellement élevé si de nombreux utilisateurs collaborent et apportent de nombreuses modifications
Andy
la source
1

Essentiellement, ce que vous demandez, c'est comment gérer un état mutable partagé. L'épargne est la partie facile; mais comment traitez-vous avec plusieurs personnes éditant la même chose en même temps? Vous souhaitez que tous les utilisateurs consultent le même document tout en synchronisant les modifications simultanées, le tout en temps réel.

Comme vous l'avez probablement compris, c'est un problème difficile! Il existe quelques solutions pragmatiques:

  1. Modifiez les exigences de votre application pour ne pas permettre une véritable édition simultanée. Les modifications peuvent être fusionnées comme avec les systèmes de contrôle de source, avec des résultats diffusés à chaque client. Vous pouvez le créer vous-même, mais ce serait une expérience utilisateur plus pauvre.
  2. Externalisez la synchronisation des mutations d'état vers une solution open source qui s'intègre à votre technologie existante. ShareDB est le leader actuel dans cet espace. Il est basé sur la transformation opérationnelle et utilisé dans au moins un système de production. Cela résoudra le problème d'enregistrement qui vous préoccupe, mais n'aidera pas avec les fonctionnalités UX supplémentaires obligatoires pour toute application collaborative.
  3. Utilisez une plate-forme standard telle que Convergence (avertissement: je suis un fondateur) pour gérer tous les éléments difficiles pour vous. Vous obtiendrez également des outils supplémentaires pour la collaboration en temps réel tels que le suivi du curseur / de la souris, les sélections et le chat pour créer rapidement une expérience de collaboration supérieure. Voir cette question pour un bon tour d'horizon de tous les outils existants.
alalonde
la source