最近在做一个剪切板同步的小工具。但是遇到了一些问题,emmm,目前还没有好的解决方案。

问题描述:

  • 这是一个分布式的剪贴板。意思是,机器A, B, C, D, E, A在剪贴板上粘贴了字符串a,B、C、D、E会得到一份copy。这样,你在机器B、C、D、E上可以用来粘贴。A、B、C、D、E上的数据要满足一致性。
  • 为保证机器之间的数据交互能够比较高效地进行,大概率可能采用组播监听的方式来维护剪贴板的历史同步。这样除了达到免去逐一发送的路由相关繁杂问题以外,还企图解决没有中心怎么办的问题。
  • 协议分为两部分:设备上线与心跳协议,设备数据传输协议。
  • 设备上线与心跳协议规定了设备在上线的时候,应该向组内的成员发送上线的advertising。在一定时间内,机器会告诉在座的各位,我还在线。(你们都是。。)(逃)
  • 数据同步协议除了需要把数据传输到在座各位,还要保证我的数据顺序是正确的,在座各位也是正确的。
    例如在某一个时刻:
    • 剪贴板cluster(emmm怎么翻译好)的链条中,主链为a--b--c--d。
      • A机器包含:a--b--c--d
      • B : a--b--c
      • C: a--b--c--d
      • D: a--b--c--d
      • 此时,A在剪贴板中粘贴了数据e。(A组播发送了e给在座各位)
      • C、D收到了:在自己的板子上默默地加上了e
      • 然而,B,说,这不对!我的链条错了,快给我修复一下!然后B从其他人那里拿数据d、e。
      • 最后,大家的链条与主链同步。

最后实现一个,拥有多机同步历史记录的剪贴板。
那么问题来了,如何实现一种协议,来同步机器之间的数据?

部分解决方案:

目前只能想到,有或可能有缺陷的解决方案。所以这还是一个未解决的问题。
1. 时间戳+数据哈希。
数据payload里包含了递增时间戳,上一个数据包的哈希,本数据包的哈希(可选)。这样,通过数据差错仲裁就可以知道谁出了问题。同样引用上面例子:
+ B收到包含pre_hash == d.hash的包,广播自己的last-timestamp或last-hash(c.hash)。其他人收到之后,也立刻广播last-timestamp或last-hash (d.hash) 。这样,少数服从多数,B错了,B从其他正确链条同步d。
那么问题来了,如果我在一个错误的链条上粘贴,却想要得到正确的结果,我就必须:
+ B广播:我粘贴了e!
+ 在座:你pre_hash错了,我们最后的数据是d。看你的操作时间戳,你确实是在粘贴了。
+ B:大哥们我错了,请其中一个把hash为pre_hash的数据给我吧。(单播获取欠缺数据)
这样的做法导致一个问题:多个数据链节丢失,你只能得到最后一个正确的节点。而且如果你再错一次,emmm,问题比较麻烦了,推理起来比较烦。当然,这里可以一次把所有丢失的节点发过去,这又是另外一回事了。以及,不同机器时间不一致怎么办。
2. raft
这个论文我还没看完,不知道管用否,以及是否适合这个微不足道的小工具。咱也不知道,咱也不敢问。。。
3. syncthing? 我参考了syncthing的代码,组播发现主机,tcp增量同步数据,看上去数据交互会有点重。但不失为一个方法。然后一路单播投递下去,也还行。再不济去找找gossip的某些实现。粗暴。

意见或建议

如果各位有好的意见或建议,衷心感谢各位留言(唱),或在我的repo发issue(跳),或者发email 给我 i@wxk.at(rap),或者发pr(篮球),都行!

5 天 后

为啥一定要自己实现一套?消息队列不好吗(逃

    hsxfjames 我觉得,消息队列通常是集群式的中间件,此处存在一个C/S的模型。但这个用例是p2p的,并不是针对谁的服务。我大概了解了一下0mq等,好像在这里,用不上。

      最近活多,该项目已鸽子两天hhh

      token7 你不是说剪贴板是分布式的吗,这不就是个聊天群吗,一个人发送了,其他人都能收到。消息队列也可以实现成多对多的,单端既可以是生产者也可以是消费者,发送时生产,接收时消费,消费异常从历史库里同步回来

        © 2018-2025 0xFFFF