

Scratch3技术分析之云变量 API(第7篇)
source link: http://wwj718.github.io/post/%E5%B0%91%E5%84%BF%E7%BC%96%E7%A8%8B/scratch3-cloud-var/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

关于云变量
我们先来看下云变量的样子:
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/
,通过这个线索,我们可以找到与云变量相关的前端源码, 源码非常简单。
值得注意的是,设置变量的过程,数据从前端发往服务端,服务端不做响应。
项目中存在云变量时,我们重新打开这个项目,默认将拉去云变量中存储的的值
删除云变量
从前端源码中似乎没看到权限相关的部分。
明天有空做个实验,试试未登录状态是否能与云变量服务进行通信。
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
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中的代码基本一致:
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测试工具
其他值得留意的问题
Send a message to the cloud server at a rate of no more than 10 messages/sec
this.sendCloudData = throttle(this._sendCloudData, 100);
Recommend
-
20
晚间必读7篇 | Chainlink的白皮书2.0提到了什么? 金色荐读 刚刚 1.能在Layer2中实现的7个操作L2扩展解决方案的时代已经到...
-
9
绿色供应链之云技术让供应链更环保 - IT业界_CIO时代网 - CIO时代—新技术、新商业、新管理绿色供应链之云技术让供应链更环保 2021-09-23 16:09:21 来源: 摘要:积极践行国家绿色发展理念,科箭推出“绿色供...
-
10
随着云原生技术的快速发展,微服务架构、容器及 Kubernetes 等技术的不断迭代,对于海量日志的管理提出了更高的要求,包括容器内磁盘是否持久化、HPA 时如何保证数据不丢失、海量日志如何进行可靠的传输、微服务数量达到一定规模时日志该如何管理、如何了解不同...
-
6
本文是Scratch3.0 技术分析之后端 API系列的第 9 篇。 backpack(书包) backpack(书包)是
-
3
本文是Scratch3.0技术分析之后端API系列的第8篇。 Studio Studio是Scratch社区的重要构成部分。 Studio在概念上颇似项目收纳盒...
-
7
我们在Scratch3技术分析之创作平台API(第1篇)定义了以下两个名词: 本文将详细讨论项目的内部数据,看看Scratch是如何精心设计这个数据结构了。 Sc...
-
5
本文将关心项目主页涉及的API。 相关的API包括: 我们以测试项目https://scratch.mit.edu/projects/277117877为例, 打开页面,加载的数据还真不少。 其中https://scratch.mit.edu/js/projects.bundle.js足有4.7M,下...
-
8
在这篇文章中,我们来重点关注Scratch静态资源相关的API, 了解这些资源是如何被存储以及如何被加载的。 关注的静态资源包括: Scratch project 中的静态资源 项目缩略图 Scratch pr...
-
2
Scratch3.0技术分析之后端API(第0篇) 2019-01-06 少儿编程
-
4
超简单的Python教程系列——第7篇:循环和迭代器 精选 原创
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK