腾讯文档多人在线编辑表格协议分析

1.初步分析

dev Tool调试发现多人在线编辑,类似于多人在线聊天,服务器负责收集客户端消息,然后集中处理服务器本地存储的文档。

调试发现,该服务基于websocket协议,通过分析ws消息流,可以得到客户端和服务器交互的方式。

  1. 客户端链接,服务器回复一条数据
  2. 客户端发送带有“client ready”的数据
  3. 客户端6秒间隔发送心跳包
  4. 接下来就可以正常发送编辑、修改的消息了

截取了一条编辑的数据,可以看到

type: USER_CHANGES

task_id: 需要和上一次上上次……不一样,建议随机数实现

c:[["BB08J2",7,7,4,4],……表示操作的单元格8行5列

"2":[165,"@\\\\℃:@"]……表示内容,修改"@\\\\℃:@"即可

这里用golang实现该ws客户端:

// Copyright 2015 The Gorilla WebSocket Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.



package main

import (
	"github.com/gorilla/websocket"
	"log"
	"os"
	"os/signal"
	"time"
)

//var addr = flag.String("addr", "localhost:8080", "http service address")

func main() {
	interrupt := make(chan os.Signal, 1)
	signal.Notify(interrupt, os.Interrupt)
    //1.创建连接
	c, _, err := websocket.DefaultDialer.Dial(wspath, nil)
	if err != nil {
		log.Fatal("dial:", err)
	}

	defer c.Close()
	done := make(chan struct{})
    //开启接收消息goroutine
	go func() {
		defer close(done)
		for {
			_, message, err := c.ReadMessage()
			if err != nil {
				log.Println("read:", err)
				return
			}
			log.Printf("recv: %s", message)
		}
	}()
    //发送client ready消息
	c.WriteMessage(websocket.BinaryMessage,[]byte(`42["post","{\"apid\":{\"s\":\"554557239478\",\"t\":1652718593193,\"i\":\"DUFpBc0JhWXRia3Vk\",\"g\":\"f7be4c0beadf755e6b25852d69c8cb83725a42a4\",\"apid\":\"\",\"r\":99},\"type\":\"CLIENT_READY\",\"task_id\":808447158586389,\"docid\":\"300000000$PZAsBaYtbkud\",\"uid\":\"144115217770477896\",\"cookie\":\" SID=6587823b09994d1c9b3ed14a1986e711715ea884b3d5487690649ecc92f23cfe;\",\"base_rev\":99,\"code_ver\":1,\"session_type\":0,\"gray\":0,\"dver\":\"2.10.0\",\"wl\":\"\",\"u\":\"7b2be78e572847379db881e1288db933\",\"generalpacket\":{\"rel_rev\":\"sheet-hotfix-20220513_1447-a8b28d0a44\",\"dver\":\"2.10.27540461\",\"right_tag\":1},\"docs_type\":\"sheet\"}\n{\"roomType\":\"padpage\",\"roomName\":\"padpage/300000000$PZAsBaYtbkud\",\"upid\":\"DUFpBc0JhWXRia3Vk\",\"gid\":\"300000000$PZAsBaYtbkud\",\"sid\":\"554557239478\",\"tid\":1652718593193,\"sig\":\"f7be4c0beadf755e6b25852d69c8cb83725a42a4\",\"data\":{\"stats\":{\"screen\":\"\"}}}"]`))
    
    //用来发送心跳消息
	ticker := time.NewTicker(6*time.Second)
	defer ticker.Stop()

	for {
		select {
		case <-done:
			return
		case <-ticker.C:
			err = c.WriteMessage(websocket.TextMessage, []byte("42[\"post\",\"{\\\"type\\\":\\\"HEART_BEAT\\\",\\\"task_id\\\":8245210039230595,\\\"docid\\\":\\\"300000000$PZAsBaYtbkud\\\",\\\"uid\\\":\\\"144115217770477896\\\"}\\n\"]"))
			if err != nil {
				log.Println("write:", err)
				return
			}
        //捕获ctrl+c,没啥卵用
		case <-interrupt:
			log.Println("interrupt")
			err = c.WriteMessage(websocket.CloseMessage, websocket.FormatCloseMessage(websocket.CloseNormalClosure, ""))
			if err != nil {
				log.Println("write close:", err)
				return
			}
			select {
			case <-done:
			case <-time.After(time.Second):
			}
			return
		}
	}
}

 就简单做了一个示例

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

星云牛马

帮到您的话,可否请我喝杯咖啡

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值