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

推荐订阅源

Vercel News
Vercel News
Recorded Future
Recorded Future
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
The GitHub Blog
The GitHub Blog
Application and Cybersecurity Blog
Application and Cybersecurity Blog
Google DeepMind News
Google DeepMind News
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
Microsoft Azure Blog
Microsoft Azure Blog
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
M
MIT News - Artificial intelligence
云风的 BLOG
云风的 BLOG
Y
Y Combinator Blog
N
News | PayPal Newsroom
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
Help Net Security
Help Net Security
博客园 - Franky
SecWiki News
SecWiki News
Recent Announcements
Recent Announcements
T
Troy Hunt's Blog
The Register - Security
The Register - Security
The Last Watchdog
The Last Watchdog
Webroot Blog
Webroot Blog
S
Security Affairs
博客园 - 司徒正美
S
Schneier on Security
I
InfoQ
博客园_首页
www.infosecurity-magazine.com
www.infosecurity-magazine.com
T
Threat Research - Cisco Blogs
Forbes - Security
Forbes - Security
腾讯CDC
N
Netflix TechBlog - Medium
N
News and Events Feed by Topic
Cloudbric
Cloudbric
T
The Exploit Database - CXSecurity.com
P
Proofpoint News Feed
A
About on SuperTechFans
Engineering at Meta
Engineering at Meta
Recent Commits to openclaw:main
Recent Commits to openclaw:main
B
Blog
V
Vulnerabilities – Threatpost
C
Check Point Blog
Google DeepMind News
Google DeepMind News
Google Online Security Blog
Google Online Security Blog
C
Cyber Attacks, Cyber Crime and Cyber Security
Hacker News - Newest:
Hacker News - Newest: "LLM"
C
Cisco Blogs
Schneier on Security
Schneier on Security
O
OpenAI News
K
Kaspersky official blog

夜行人

回家路上 第一期的直播演示项目 震动检测器 正能量 在线参观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 Scratch3技术分析之云变量 API(第7篇) [译]对管道(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开发笔记 创业二三事
Pharo使用笔记之http、websocket与mqtt
种瓜 · 2019-06-06 · via 夜行人

文章目录

前言

Smalltalk提供了绝佳的可探索的沉浸式编程环境(live),这是一种"红药丸",一旦尝试就再也回不去了。于是决定将原型构建相关的工作都放到Pharo上。

许多业务相关的代码可能以服务的方式跑在外部,于是进程间通信(IPC)就成了实际需要。本文关注http、websocket与mqtt这几种我常用的通信策略。 (本文只关注在Pharo中运行客户端)

日后有时间可能会加上Socket、ZeroMQ、RPC。

以及是我的使用笔记。

环境

目前我在MacOS 10.13.5下使用Pharo 7.0.3.

关于http的知识在此就不多说了,如果不熟悉可以参考wikipedia http

在Pharo中,我倾向于使用Zinc作为http client。

Zinc文档很齐全。Zinc既可以作为http server,也可以作为http client

如果你希望构建web server,Seaside可能会更合适。我们接下来关注如何将Zinc用作http client。

我们将httpbin.org用作测试服务器。

安装依赖

Zinc已经内置在Pharo7 (更早的版本不大清楚)。所以无需安装依赖。

实验

让我们向https://httpbin.org/get发送请求。

response
1
2
3
4
ZnClient new
   url: 'https://httpbin.org/get';
   get;
   response.

输出response

将response输出到Transcript中。

1
2
3
4
5
6
7
| response |
response := (ZnClient new)
   url: 'https://httpbin.org/get';
   get;
   response.
response writeOn: Transcript.
Transcript flush.

request
1
2
3
4
5
6
7
| request |
request := (ZnClient new)
   url: 'https://httpbin.org/get';
   get;
   request.
request writeOn: Transcript.
Transcript flush.

超时
1
2
3
ZnClient new
   timeout: 1;
   get: 'https://httpbin.org/get'.
retry
1
2
3
4
5
ZnClient new
   logToTranscript;
   numberOfRetries: 3;
   retryDelay: 2;
   get: 'https://httpbin.org/get'.
URL构造
1
2
3
4
5
ZnClient new
   https;
   host: 'httpbin.org';
   addPath: 'get';
   get.
1
2
3
4
5
6
7
ZnUrl new
   scheme: #http;
   host: 'www.google.com';
   port: 80;
   addPathSegment: 'search';
   queryAt: 'q' put: 'Pharo Smalltalk';
   yourself.
提交HTML表单
1
2
3
4
<form action="search-handler" method="POST" enctype="application/x-www-form-urlencoded">
   Search for: <input type="text" name="search-field"/>
   <input type="submit" value="Go!"/>
</form>

表单使用默认编码application/x-www-form-urlencoded

1
2
3
4
ZnClient new
   url: 'https://httpbin.org/post';
   formAt: 'search-field' put: 'Pharo Smalltalk';
   post.

上传文件

1
2
3
4
<form action="upload-handler" method="POST" enctype="multipart/form-data">
   Photo file: <input type="file" name="photo-file"/>
   <input type="submit" value="Upload!"/>
</form>
1
2
3
4
5
6
ZnClient new
   url: 'https://httpbin.org/post';
   addPart: (ZnMimePart
                fieldName: 'photo-file'
                fileNamed: '/tmp/test.jpeg'); "todo:有问题?"
   post.

ZnClient new request headers at: 'accept' put: 'text/*'.

提交json数据

jwt认证

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
|cli headers|
cli := ZnClient new.
headers := cli request headers.
headers at: 'Content-Type' put: 'application/json'.
headers at: 'Authorization' put: 'Bearer ACCESS_TOKEN'.
cli
    url: 
'https://httpbin.org/post';
    entity: (ZnEntity 
        with:'{"hello": "world"}'
        type: ZnMimeType applicationJson);
    post;
	response.

websocket

安装依赖

1
2
3
4
5
Gofer new
   smalltalkhubUser: 'SvenVanCaekenberghe' project: 'ZincHTTPComponents';
   package: 'ConfigurationOfZincHTTPComponents';
   load.
(Smalltalk globals at: #ConfigurationOfZincHTTPComponents) project latestVersion load: 'WebSocket'.

实验

选择www.websocket.org作为测试服务器。 也可以使用wssh帮助测试,wssh类似netcat。

让我们向wss://echo.websocket.org发送请求。

1
2
3
4
5
| webSocket |
webSocket := ZnWebSocket to: 'wss://echo.websocket.org'.
[ webSocket
   sendMessage: 'Pharo Smalltalk using Zinc WebSockets !';
   readMessage ] ensure: [ webSocket close ].

做实验的时候,可能希望sendMessagereadMessage是分别手动操作的。

对于sendMessage比较简单:

1
2
[ webSocket
   sendMessage: 'Pharo Smalltalk using Zinc WebSockets !'; ] value.

readMessage时可能会阻塞整个软件。推荐使用taskit来并行执行。

首先安装依赖:

1
2
3
4
Metacello new
  baseline: 'TaskIt';
  repository: 'github://sbragagnolo/taskit';
  load.

taskit的使用非常简单:[ 1 second wait. 'Waited' logCr ] schedule.,打开Transcript,运行后,可以看到1秒后有一条消息打印在Transcript上。

使用taskit来运行readMessage

1
2
[ (webSocket
   readMessage) logCr ]  schedule.

webSocket readMessage每次读取一条消息,当没有消息时,会阻塞。

MQTT

测试服务器使用iot.codelab.club,测试账号为guest:test.

###安装依赖 第一个例子里,我们准备使用Pharo的MQTT client发布一个消息:hello from pharo, 使用hbmqtt订阅它。

首先让我们在Pharo中安装MQTT client, 我偏好svenvc/mqtt, svenvc是smalltalk社区的活跃用户,维护了好几个重要的库,代码质量非常高,由于smalltalk社区很小,所以不要在意star数。 使用iceberg安装它,记得load相应的package(全部load即可)。

接着在系统命令行里安装Python库hbmqtt,用于配合测试: pip install hbmqtt

实验

发布消息

在命令行里运行hbmqtt_sub --url mqtt://guest:test@iot.codelab.club -t "/pharo_mqtt"

接着在Pharo里发布消息,

1
2
3
4
5
6
7
8
9
|client|
client := MQTTExperimentalClient new
    atLeastOnce; "QoS level 1"
    host: 'iot.codelab.club';
    username: 'guest';
    password: 'test';
    open;
    sendMessage: 'hello from pharo' asByteArray toTopic: '/pharo_mqtt';
    close.

消息发布成功!

订阅消息
1
2
3
4
5
6
7
8
9
|client|
client := MQTTExperimentalClient new
    atLeastOnce; "QoS level 1"
    host: 'iot.codelab.club';
    username: 'guest';
    password: 'test';
    open;
    subscribeToTopic: '/hello_pharo';
    readMessage.

hbmqtt_pub --url mqtt://guest:test@iot.codelab.club -t "/hello_pharo" -m "hello from hbmqtt"

前头的程序接受1条消息就退出(阻塞式的)

写一个接收3条消息才退出的程序

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
|client|
Array streamContents: [ :stream | | count |
   count := 1.
   MQTTExperimentalClient new
    host: 'iot.codelab.club';
    username: 'guest';
    password: 'test';
    open;
    subscribeToTopic: '/3_messages';
    runWith: [ :message |
        stream nextPut: message.
        (count := count + 1) > 3 ifTrue: [ ConnectionClosed signal ] ] ].

连续发三条消息:

1
2
3
hbmqtt_pub --url mqtt://guest:test@iot.codelab.club -t "/3_messages" -m "hello1"
hbmqtt_pub --url mqtt://guest:test@iot.codelab.club -t "/3_messages" -m "hello2"
hbmqtt_pub --url mqtt://guest:test@iot.codelab.club -t "/3_messages" -m "hello3"

提醒

smalltalk社区习惯在class里加上comment和tests,而不是单独构建文档,所以你在svenvc/mqttreadme里基本读不到文档,在Pharo编程环境里去通过阅读、批注和tests去学习使用方法吧。这种方式充满乐趣,你可以拆开任何黑盒子,一探究竟。