-
Notifications
You must be signed in to change notification settings - Fork 72
消息结构
Codelab Adapter的设计追随Smalltalk的设计原则everything is message
.
消息的基础结构为
{ "topic": "TOPIC", "payload": "MESSAGE" }
注意: 此结构与MQTT消息结构保持一致。
插件消息的topic由插件作者自定义,一般而言,由插件名决定。 举几个例子:
{"topic": "eim", "payload": "YOUR_MESSAGE"}
{"topic": "eim/python", "payload": "YOUR_MESSAGE"}
以下两种情况,建议 topic直接用eim
:
- 测试阶段
- 不想构建独立Scratch extension
基于消息的系统一般都是异步非阻塞的。前头的两个插件都是异步的。
如果你希望基于消息构建同步插件(按顺序、阻塞式地逐个积木执行),可以参考这篇文章,核心思路是在消息结构里加上消息id(Scratch Link也是这么做的)
看几个例子
{"topic": "eim/reqRep", "payload": "YOUR_MESSAGE"}
// MESSAGE_ID来自前端
{"topic": "eim/cozmo", "payload": "YOUR_MESSAGE", "messageID": "MESSAGE_ID"}
消息是Codelab Adapter的核心机制,Codelab Adapter使用系统消息
来构建部分系统功能(有别于插件消息)。
随着功能需求的增长,这类消息会陆续增多。
目前有两个系统消息
CONTROL_TOPIC = "__control"
WORMHOLE = "__wormhole"
CONTROL_TOPIC用于控制插件的启停, WORMHOLE用于classroom
功能(暂未发布,可以忽视)。
CONTROL_TOPIC用于以下几个功能
Codelab Adapter 的extension由线程启动。
Python的线程无法像进程和协程一样被管理,目前使用python3-cookbook的建议来管理线程。
但有一个问题,试看extension_eim.py的代码
while self._running:
read_message = self.read() # 不能有多个read
topic = read_message.get("topic")
if topic == self.TOPIC:
data = read_message.get("payload")
self.logger.info("eim message:%s", data)
由于self.read()
是阻塞的,所以即便在Codelab Adapter里取消勾选停止了插件(self._running
变为False),但依然需要scratch里多发一条消息,才能结束self.read()
的阻塞,退出while。
所以这种情况下,当用户在Codelab Adapter暂停插件时,会触发一条消息:
{"topic":CONTROL_TOPIC, "payload":"terminate","type":"adapter"}
打破self.read()
阻塞。
从前端开启插件的消息为:
{
"topic": CONTROL_TOPIC,
"type": "web/extension_control",
"payload": { "action": "turn_on", "extension_name": "extension_eim" }
}
CodeLab Adapter将定时汇报插件状态(这样可以支持多个前端,类似linux GUI与server分离)
{
"message": {
"topic": CONTROL_TOPIC,
"payload": {
"extension_iot": false,
"extension_eim": true,
"extension_vector": false,
"extension_eim_monitor": false,
"extension_tello": false,
"extension_blender": false,
"extension_mpfshell": false,
"extension_eim_script": false,
"extension_python_kernel": false,
"extension_wechat": false,
"extension_cozmo": false,
"extension_usb_microbit": false
},
"type": "event/extensions_statu"
}
}
实现类似Scratch Link的交互:在前端选择硬件。
思路:分析Scratch micro:bit extension与Scratch Link通信的细节,模仿它:Scratch micro:bit extension与Scratch Link通信的细节
request from scratch
{
"messageID": MESSAGE_ID,
"topic": CONTROL_TOPIC,
"type": "web/devices_control",
"payload": { "action": "discover", "extension_name": "extension_usb_microbit" }
}
response from codelab adapter extension(定时扫描回复)
{
"messageID": MESSAGE_ID,
"topic": CONTROL_TOPIC,
"type": "web/devices_control",
"payload": { "devices_type": "PORT", "names": ["COM2","COM3"] }
}
{
"messageID": MESSAGE_ID,
"topic": CONTROL_TOPIC,
"type": "web/devices_control",
"payload": { "action": "connect", "extension_name": "extension_usb_microbit", "name": "COM2"}
}
response from codelab adapter extension
{
"messageID": MESSAGE_ID,
"topic": CONTROL_TOPIC,
"type": "web/devices_control",
"payload": { "status":"success"}
}