惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

K
Kaspersky official blog
T
Threat Research - Cisco Blogs
N
News and Events Feed by Topic
Hacker News: Ask HN
Hacker News: Ask HN
Project Zero
Project Zero
Application and Cybersecurity Blog
Application and Cybersecurity Blog
博客园 - 叶小钗
Security Latest
Security Latest
Spread Privacy
Spread Privacy
aimingoo的专栏
aimingoo的专栏
N
News and Events Feed by Topic
Webroot Blog
Webroot Blog
U
Unit 42
Cyberwarzone
Cyberwarzone
小众软件
小众软件
Scott Helme
Scott Helme
Engineering at Meta
Engineering at Meta
Microsoft Security Blog
Microsoft Security Blog
T
The Blog of Author Tim Ferriss
A
About on SuperTechFans
爱范儿
爱范儿
S
Schneier on Security
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
Schneier on Security
Schneier on Security
Latest news
Latest news
GbyAI
GbyAI
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
Simon Willison's Weblog
Simon Willison's Weblog
The Register - Security
The Register - Security
WordPress大学
WordPress大学
博客园_首页
Blog — PlanetScale
Blog — PlanetScale
PCI Perspectives
PCI Perspectives
Jina AI
Jina AI
AI
AI
NISL@THU
NISL@THU
I
Intezer
G
GRAHAM CLULEY
B
Blog
S
Secure Thoughts
IT之家
IT之家
宝玉的分享
宝玉的分享
Recent Announcements
Recent Announcements
Y
Y Combinator Blog
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
酷 壳 – CoolShell
酷 壳 – CoolShell
有赞技术团队
有赞技术团队
V2EX - 技术
V2EX - 技术
Recorded Future
Recorded Future
Hacker News - Newest:
Hacker News - Newest: "LLM"

夜行人

回家路上 第一期的直播演示项目 震动检测器 正能量 在线参观CodeLab Neverland 发布 CodeLab Adapter 3.3.1 DynamicTable 之 纸糊方向盘 CodeLab DynamicTable: 一个可实施的技术方案 CodeLab Insight 发布 Alpha 版 情人节 Home Assistant 周报 && IoT 周报 (02) Joplin: 关注隐私的 Evernote 开源替代软件 浏览器的未来与 Web 传感器 Home Assistant 周报 && IoT 周报 (01) 百宝箱(01) 论自由 介绍 WebThings Home Assistant 周报 && iot 周报 (00) 百宝箱(00) 毛姆读书心得 传世之作 周末徒步 CodeLab Adapter ❤️ Jupyter/Python 航班 躲雨 夏令营途中 [译]思想--作为一种技术 The future of coding 美国之行 三门问题的程序模拟 从Python转向Pharo https://blog.just4fun.site/post/iot/iot-open-source-projects/ Python异步编程笔记 https://blog.just4fun.site/post/iot/iot-open-source-hardware-community/ 万物积木化开发者社区 CodeLab ❤️ Blender [译]对管道(Pipes)的偏爱 [译]提出正确的问题比得到正确答案更重要 蓝牙设备与Scratch3.0 创建你的第一个Scratch3.0 Extension Scratch3技术分析之项目内部数据(第6篇) Scratch3技术分析之社区 API(第5篇) Scratch3技术分析之User API(第4篇) Scratch3技术分析之项目主页API(第3篇) Scratch3技术分析之静态资源API(第2篇) Scratch3.0、micro:bit与Windows7 https://blog.just4fun.site/post/iot/zerynth-vs-micropython/ 核聚变、方所与半宅空间 可视化编程为何是个糟糕的主意 codelab.club周末聚会 关于codelab.club '下一件大事'是一个房间 Hungry Robot - Eat everything 编程作为一种思考方式 今日简史 史蒂夫·乔布斯传 罗素自选文集 https://blog.just4fun.site/post/edx/tianjin-scratch-ai/ https://blog.just4fun.site/post/edx/richie-cms-openedx/ 徒步武功山 WebUSB与micro:bit 积木化编程与3D场景 夜宿武功山顶 scratch3-adapter接入优必选Alpha系列机器人 https://blog.just4fun.site/post/edx/video-migration-note/ scratch3-adapter重构笔记 https://blog.just4fun.site/post/edx/edx-community-members/ 两种硬件编程风格的比较 使用micro:bit自制PPT翻页笔 柏拉图对话集 scratch3.0 + micro:bit 七月电影放映计划 非营利组织的管理 Screenly--用树莓派让任何屏幕变为可编程的数字标牌 以最佳实践开始你的Django项目 micro:bit与事件驱动 为Scratch3.0设计的插件系统(上篇) OCR应用一例 近两年读过的一些好书 blockly开发之使用python驱动浏览器中的turtle(2) 牛顿新传 文学理论入门 逻辑的引擎 人生的意义 blockly开发之生成并运行js代码(1) blockly开发之hello world(0) micro:bit使用笔记 神器之Termux https://blog.just4fun.site/post/iot/micropython-notes/ Cozmo what is this Scratch的前世今生 下段旅程 我行在远方 爆裂 途中杂记 https://blog.just4fun.site/post/edx/open-edx-startup/ cozmo系列之入门 - 有性格且可编程的机器人 PaperWeekly开发笔记 创业二三事 blockly与结对编程
Scratch3技术分析之云变量 API(第7篇)
种瓜 · 2019-03-04 · via 夜行人

文章目录

关于云变量

我们先来看下云变量的样子:

Scratch团队在FAQ里解释了

什么是云变量

云变量可以让作品里保存的数据与Scratch社区的其他人所共享。你可以利用云变量发布调查或其他作品,而社区中的其他人可以访问和修改这些数据。

谁能看见云变量中存放的数据?

当你运行一个用了云变量的作品时,你使用过程中产生的数据会存放在你的用户名下,其他人可以看到这些数据。

云变量可以存放什么类型的数据?

云变量只能存放数字。

我能使用云变量创建聊天室吗?

不可以。虽然在技术上是可能的,但Scratch网站不允许这样做。

谁可以改变云变量的内容?

只有你和项目的查看者才能将数据存储在项目的云变量中。 如果人们进入项目内部源码或重新混合(remix)你的代码,将会创建变量的副本,而不会影响或更改原始变量。

可以用云变量创作多人游戏吗?

由于网速和同步的问题,创作多人游戏比较困难。但仍然有一些Scratcher别出心载,使用云变量制作回合制游戏以及其他类型的游戏。

云变量会在后台产生日志。每个项目最多有10个云变量。

Scratch新用户可能无法使用云数据。Scratch团队不希望Scratch新手滥用云变量,因为它可能会给系统带来很大的负担。

云变量会自动更新,利用这个特性,可以建立联机游戏和聊天室,但官方不希望有高频交互,这将带来服务器压力。此外,实时性也不能保证,如果你希望建立实时的强连接,参考codelab-adapter的虫洞(wormhole)


说了半天,你可以看一个带有云变量的项目Google Chrome Dino Run 2 remix

解释完了云变量,我们进入技术分析部分,我们试图回答: 云变量是怎么实现的,并给出简单的实现例子。

分析

和之前的分析一样,借助Chrome DevTools,我们来观察创建和使用云变量的过程中都发生了什么。

创建变量

注意: 你的账号不能是新注册的,否则你没有创建云变量的权限。

创建我们的第一个云变量: test_cloud_var

来看看请求细节(Headers)

Sec-WebSocket-Key 是一个Base64 encode的值,这个是浏览器随机生成的。websocket中似乎没有处理用户凭证相关的问题。

接着看看Frames:

向上的箭头表示的数据流向为 client(scratch-gui)-> server 向下的箭头表示的数据流向为 server-> client

创建变量的过程非常简单:

  • 建立websocket通道
  • 在websocket通道中来回传送json。采用类似json-rpc的交互方式。

后端的云变量服务地址位于wss://clouddata.scratch.mit.edu/,通过这个线索,我们可以找到与云变量相关的前端源码, 源码非常简单。

设置变量

值得注意的是,设置变量的过程,数据从前端发往服务端,服务端不做响应。

刷新项目

项目中存在云变量时,我们重新打开这个项目,默认将拉去云变量中存储的的值

删除云变量

权限问题

前端源码中似乎没看到权限相关的部分。

明天有空做个实验,试试未登录状态是否能与云变量服务进行通信。

1
2
3
4
5
6
7
8
9
var ws = new WebSocket('wss://clouddata.scratch.mit.edu/');
ws.onopen = function(evt) { 
  var data = {"method":"handshake","user":"wwj718","project_id":"291228938"}
  ws.send(JSON.stringify(data)+"\n");
};

ws.onmessage = function(evt) {
  console.log( "Received Message: " + evt.data);
};    

实验发现只有在登陆情况下,才能建立websocket连接。websocket在建立连接的时候会携带cookie,这就是实现用户身份验证的关键。

实现一个云变量服务

下边我们给出兼容Scratch开源前端的云变量后端实现。这个实现只作为原理展示,如果你要用于生产环境,需要做些调整。

该实现基于Python的websockets

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
import json
import asyncio
import websockets
# json-rpc

def handshake(req_json):
    # 返回项目中已有的云变量
    project_id = req_json.get("project_id")
    result = {"method":"set","project_id":project_id,"name":"☁ test","value":"0"}
    return result

def create(req_json):
    # {"method":"create","user":"wwj718","project_id":"291229535","name":"☁ test1","value":0}
    name = req_json.get("name")
    return {"method": "ack", "name": name, "reply": "OK"}

def set(req_json):
    # {"method":"set","user":"wwj718","project_id":"291229535","name":"☁ test1","value":"0"}
    return None

def delete(req_json):
    # {"method":"delete","user":"wwj718","project_id":"291229535","name":"☁ test1"}
    return None

method_map = {}
method_map["handshake"] = handshake
method_map["create"] = create
method_map["set"] = set
method_map["delete"] = delete

async def handle_cloud_data(websocket, path):
    async for message in websocket:
        # from IPython import embed;embed()
        # message结尾有换行符\n, 流
        req_json = json.loads(message.strip())
        print("request data:",req_json)
        method = req_json.get("method")
        handle = method_map.get(method)
        if handle:
            result = handle(req_json)
        await websocket.send(json.dumps(result))


asyncio.get_event_loop().run_until_complete(
    websockets.serve(handle_cloud_data, '0.0.0.0', 8765))
print("server is running")
asyncio.get_event_loop().run_forever()

测试代码与scratch-gui中的代码基本一致:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
var ws = new WebSocket('ws://127.0.0.1:8765');
ws.onopen = function(evt) { 
  var data = {"method":"handshake","user":"wwj718","project_id":"291228938"}
  ws.send(JSON.stringify(data)+"\n");
};

ws.onmessage = function(evt) {
  console.log( "Received Message: " + evt.data);
};    

// var data = {"method":"set","user":"wwj718","project_id":"291228938","name":"☁ test1","value":"1"}
// ws.send(JSON.stringify(data)+"\n")

如果你要用于生产环境,还需要处理cookie和多个客户端一同读写云变量的问题(考虑到读写频率,推荐使用redis, 如果你的后端也用python异步api实现,推荐使用aioredis)。

websocket测试工具

Socket Wrench

其他值得留意的问题

速率限制

throttle 10:

Send a message to the cloud server at a rate of no more than 10 messages/sec

this.sendCloudData = throttle(this._sendCloudData, 100);

参考: