查找已更改内容并仅上传更改部分。

8
我是一名有用的助手,可以为您翻译文本。

我只是在这里寻找想法/建议;我并不要求完整的解决方案(尽管如果您有解决方案,我很乐意看看)

我正在尝试找到一种仅上传文本更改的方法。它最有可能作为基于jQuery和HTML运行的云应用程序使用,后端由PHP服务器运行。

例如,如果我有以下文本:

asdfghjklasdfghjkl

我把它改成了

asdfghjklXasdfghjkl

我不想上传整个内容(文本可能会很长)

例如,发送到服务器的8,X可以表示: 在第8个位置添加X

或者D8,3可以表示: 转到第8个位置并删除前3个项

然而,如果单个请求在传输到服务器时损坏,由于位置将被更改,整个文档可能会损坏。一个简单的哈希可以检测到损坏,但如何从损坏中恢复?客户端将拥有所有数据,但数据可能非常大,并且不太可能上传。

因此,感谢您阅读这篇文章。以下是需要建议的简短摘要

  • 更改/修改检测
  • 通信更改的方法
  • 从损坏中恢复
  • 其他需要改进的方面

2
有趣的问题..你将不得不处理并发问题。也许可以发送按键或在固定时间间隔内将更改存储到服务器上,并使用修订号进行检查。一个问题是,如果文本(非常)大,您可能也会在客户端处理它时遇到麻烦。 - Hamish
@Hamish:为解决你的问题,我将使用jQuery获取设备的屏幕尺寸,服务器将发送足够填充3倍屏幕的文本。然后,当用户滚动时,剩余的文本可以流式传输。我喜欢你关于时间/修订的建议。我一定会记在心里。 - Kranu
除非你的屏幕像素分辨率比其他人都大,否则三个屏幕的文本并不是那么多数据要处理。我猜大约50-100kb,将整个内容发送到服务器有什么问题吗? - joni
你可能想把“数据损坏检测”加入到你的列表中。 - Iain
Joni,你误解了我的意思。这段文本非常长,但我只计划每次发送大约3屏幕的文本。 - Kranu
3个回答

4

已经有一种被接受的形式来传输这种“差异”信息,它被称为统一差异

google-diff-match-patch提供了Java、JavaScript、C++、C#、Lua和Python的实现。

您应该能够在客户端变量中保留“原始文本”和“修改后文本”,然后通过javascript(通过diff-match-patch)生成差异,在发送到服务器时附带哈希值,然后在服务器上重新构建它(使用diff-match-patch或unix的“patch”程序)。

你可能还想考虑在首次向客户端发送原始文本时包括一个“版本”(或修改日期)。然后在客户端发送的“差异请求”中包括相同的版本号(或日期)。在应用差异之前,在服务器上验证版本,以确保在进行修改时服务器上的文本副本没有与客户端的文本副本分歧。(当然,为了使此方法奏效,您需要每次更新主副本时在服务器上更新版本号)。


哇,谷歌有一些非常有趣的项目正在进行中,但我不会怀疑他们已经完成了我正在尝试做的事情。不幸的是,我现在没有完整的电脑,但我会尽快查看那个项目。 - Kranu

1

你的方法很有趣。但如果文本文件真的太大了,每次上传都需要太多时间,为什么要把整个文件发送给客户端呢?客户端真的需要接收整个5MB的文本文件吗?难道不可能只发送他需要的部分吗?

无论如何,回答你的问题: 当听到“大型文本文件”和修改检测时,我首先想到的是diff。关于算法,请阅读这里。这可以是提交更改的一种方法,并且它指定了一种格式。你只需要在JavaScript中重建diff(或其中的一部分)。这并不容易,但我认为是可能的。如果该算法对你没有帮助,那么至少差异文件格式的定义会有所帮助。

关于数据损坏问题:您不必担心您的日期在传输过程中被损坏,因为HTTP协议基于TCP协议,它会确保所有内容都没有被损坏。您应该担心的是连接重置。您可以尝试像握手一样的操作吗?当客户端向服务器发送更新时,服务器会应用修改并保留文件的旧版本。为了确保客户端已经收到了来自服务器的确认信息,证明修改已经成功(这就是连接重置发生的地方),客户端会向服务器发送另一个ajax请求。如果在一定时间内服务器没有收到此请求,则服务器上的文件将被重置。
另外一件事:我不知道JavaScript是否喜欢处理如此巨大的文件/数据...

我只会发送用户在屏幕上看到的内容。例如,当您打开Google Reader时,它只会加载几篇文章,但是随着您滚动浏览文章,它会加载更多。如果数据太多,一旦离开视口,我可以将其删除。感谢您建议使用diff。我稍后会查看它。即使我无法将其移植到JavaScript中,我相信该算法对我仍然有用。 - Kranu

1

这听起来像是版本控制系统(CVS、SVN、Git、Bazaar)已经很好地解决了的问题。

它们都相当容易在服务器上设置,并且您可以通过PHP与它们通信。

设置完成后,您将免费获得:版本控制、日志、回滚、处理并发更改、适当的差异语法、标记、分支等等。

您将无法获得您所要求的“仅发送更新”的功能。我不确定这对您有多重要。就带宽而言,纯文本的发送成本非常低廉。

个人而言,我可能会做出类似维基百科的妥协。将整个文本分解为更小的语义连贯块(章节,甚至段落),在客户端确定哪些块已被编辑(而不是到字符级别),然后发送这些块。

然后,服务器可以用您的版本控制系统生成的差异进行回答,这是它们非常高效的事情。如果您想允许并发更改,您可能会遇到编辑器必须手动合并的情况。

另一个一般的提示可能是看看Google在Wave上做了什么。我必须保持一般性,因为我自己没有详细研究过它,但我似乎记得有一些文章介绍了他们如何解决实时并发编辑问题,这似乎正是你想要做的。

总之,我认为你计划解决的问题远非琐碎,已经有许多工具可以解决许多相关问题,我个人会妥协并重新制定方法,以减少工作量。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接