一件 T恤引发的跨洋 Rust 程序员之间故事

一件 T恤引发的跨洋 Rust 程序员之间故事

又名:10分钟让你的 Rust 代码进入生产环境


Rust 大佬 Steve Klabnik 在线发推“求助”,怎么在 IOS 里把自拍的照片水平翻转,让新得的 T-shirt 的 logo 能够正常显示?

Steve 是 Rust 语言圣经 The Rust Programming Language 一书的作者。此书最近出了中文版《Rust 权威指南》。


此条“求助”发出后,鉴于 Steve 的江湖地位,众人纷纷开始支招。答案五花八门,甚至有人录起了小视频,手把手教怎么在苹果手机翻转图片,就怕 TA 学不会。


这条推特发的是在美国白天,7个小时后,位于澳大利亚的程序员 Tim McCallum 醒来了,看到这条推下面的答案,觉得这种手动 fix 不是程序员应有的修养。于是自己上手开发了一个 Rust web 服务来解决这个问题。

Tim 是 Second State 的核心开发,著有软件Second State FaaS — 为 Rust 函数提供一个快速可用的 Web 服务环境。



然而,10分钟后, Tim 就带着他用 Rust 函数实现的的图片翻转服务回来了,告诉 Steve,一个基于 Rust 的翻转即服务已经诞生啦!手机端、PC 端都可用,1秒钟就能快速实现图像翻转。



来,上效果图!


好了,现在大家都知道 Steve 在 oxide 这家公司工作啦!


快来点击这个网站,体验用 Rust 函数实现的图像翻转服务吧!


用 Rust 进行图像处理的库非常多, Tim 在开发这个Rust FaaS 时就用了 image 库。用 Rust 处理图像并不难,需要花时间的是如何让这个程序简单易用。

通常情况下,我们在 linux 上写 Rust 函数,写完之后进行编译,编译之后的程序不可能放在手机上运行。这样就需要我们在 PC 端,不断使用命令行,复制粘贴,来回折腾好几次,最后才能发到手机上。


但是,我们能不能有一个简单的方法? 可以把 Rust 函数直接放到 web 服务上,更加方便使用。

这就诞生了专为 Rust 打造的 Second State FaaS,就能快速实现 Rust 的web 服务,让 Rust 函数人人可用!


如何快速发布用 Rust 编写的 Web 服务

软件准备

最简单、最快的的方式是 ork wasm-learning github repo,然后使用 github codespaces 打开这个 github repo,根据自己的应用需求修改 src 文件夹下的 Rust 代码就可以提供 web 服务了。


当然,老司机也可以使用 docker image 或者在 Ubuntu 20.04 上安装 Rustssvmup

$ docker pull secondstate/ssvm-nodejs-starter:v2  
$ docker run -p 3000:3000 --rm -it -v $(pwd):/app secondstate/ssvm-nodejs-starter:v2  
(docker) # ssvmup build
... ...  

Rust 代码

use wasm_bindgen::prelude::*; 
use image::{ImageOutputFormat, GenericImageView, ImageFormat};  

#[wasm_bindgen]
pub fn flip(img_buf: &[u8]) -> Vec<u8> {
     println!("image size is {}", img_buf.len());
     let img = image::load_from_memory(img_buf).unwrap();
     let (w,h) = img.dimensions();
     println!("Image size {} {}", w, h);
     println!("Drawing ...");
     let filtered = img.fliph();
     println!("Returning ..."); 
     let mut buf = vec![];
     let image_format_detected: ImageFormat = image::guess_format(img_buf).unwrap();
     match image_format_detected {
         ImageFormat::Gif => {
             filtered.write_to(&mut buf, ImageOutputFormat::Gif).unwrap();

          }, 
         _ => {
             filtered.write_to(&mut buf, ImageOutputFormat::Png).unwrap();
         },
     }
     return buf;
 } 


编译并部署 Rust 函数

使用 ssvmup 工具将 Rust 函数编译成 WebAssembly 函数。编译好的 wasm 文件将保存在 pkg 目录中。

$ ssvmup build


将在 pkg 目录的 .wasm 文件上传到 Second State FaaS 中的 /api/executables RPC 服务端点中。上传之前,记得检查 .wasm 的文件名。

$ curl --location --request POST 'https://rpc.ssvm.secondstate.io:8081/api/executables' \ 
--header 'Content-Type: application/octet-stream' \ 
--header 'SSVM-Description: flip' \ 
--data-binary '@pkg/hello_lib_bg.wasm'

.wasm 文件上传完成后,Second State FaaS 将返回 wasm_idwasm_id 可以访问已经部署好的 wasm 文件里的函数。


调用 FaaS 功能


现在可以通过 web 调用 Rust 函数了!RPC 服务端点在 /api/multipart/run/wasm_id/function_name ,其中 wasm_id 是刚刚部署的 Wasm 文件的 ID,function_name 是我们要在 wasm 文件中调用的函数名称 flip。

$ curl --location --request POST 'https://rpc.ssvm.secondstate.io:8081/api/multipart/run/222/flip/bytes' \ 
--header 'Content-Type: multipart/form-data' \ 
--form 'input_1=@test/oxide.png' \ 
--output tmp.png


Web UI


测试完成后,就可以发布一个网站,让更多人方便地使用 Rust FaaS。下面是对此 FaaS 函数进行 AJAX 调用的 JavaScript 代码。

 $.ajax({
       url: "https://rpc.ssvm.secondstate.io:8081/api/run/161/say",
       type: "post",
       data : $('#input').val(),
       contentType: "text/plain",
       processData: false,
       success: function (data) {
         $('#result').html(data);
       }
 }); 


点击这里可以访问 live demo。 Rust FaaS 把 Rust 函数带到了 web 服务中,让 Rust 使用的范围更广。


最后,撒泼打滚求个 github star!这个 github repo 有很多与 Rust、WebAssembly 相关的学习资源。



发布于 2020-11-18 17:41