使用elysiajs,实现一个ffi运行在worker的a+b计算的接口

elysia 是一个bunjs web框架,通过 Bun 运行时、静态代码分析和动态代码注入增效,成为性能最佳的 TypeScript 框架之一。可与 Go 和 Rust 相媲美,发展了快2年也是出了1.0稳定版本,bun现在也支持windows了,bun听说很快,让我来看看怎么个事。

话不多说直接开始,首先安装一下bunjs

bash 复制代码
# windows
powershell -c "irm bun.sh/install.ps1 | iex"

# mac & linux
curl -fsSL https://bun.sh/install | bash

然后使用bun create elysia app创建一个名为app的elysia项目,我这边同时安装一下prisma和eslint,如果不操作数据库,且不需要eslint那么则跳过当前部分,在bun项目中使用prisma文档,eslint 由于不想配置,直接使用@antfu/eslint-config

bash 复制代码
bun add eslint @antfu/eslint-config

如果安装缓慢,在项目根目录创建bunfig.toml,为当前项目的bun设置淘宝镜像

bash 复制代码
[install]
registry = "https://registry.npmmirror.com/"

项目根目录创建eslint.config.mjs

js 复制代码
// eslint.config.mjs
import antfu from '@antfu/eslint-config'

export default antfu()

安装swagger @elysiajs/swagger

这边我选择使用rust来对接,安装rust直接找个空文件夹创建一个add.rs

rust 复制代码
// add.rs
#[no_mangle]
pub extern "C" fn add(a: i32, b: i32) -> i32 {
    a + b
}

然后终端执行rustc --crate-type cdylib add.rs打包成插件给bun调用 将打包后的libadd文件放入elysia项目根目录新建文件夹libs下,/libs/libadd.dylib。

src下创建worker.ts文件,把下面代码复制进去

ts 复制代码
// /src/worker.ts
/* eslint-disable no-var */

import { FFIType, dlopen, suffix } from 'bun:ffi'

declare var self: Worker

const path = `libs/libadd.${suffix}`
const { symbols: {
  add,
} } = dlopen(path, {
  add: {
    args: [FFIType.int, FFIType.int],
    returns: FFIType.int,
  },
})

self.onmessage = (event: MessageEvent) => {
  const res = add(event.data.a, event.data.b)

  postMessage(res)
}
ts 复制代码
// /src/index
import { Elysia, t } from 'elysia'
import { swagger } from '@elysiajs/swagger'

const app = new Elysia()
app.use(
  swagger({
    provider: 'swagger-ui',
  }),
)

const worker = new Worker(new URL('worker.ts', import.meta.url).href)
function getWorker(a: number, b: number) {
  return new Promise<number>((resolve) => {
    worker.onmessage = (event) => {
      resolve(event.data)
    }
    worker.postMessage({
      a,
      b,
    })
  })
}
app.get('/add', async ({ query }) => {
  return getWorker(Number(query.a), Number(query.b))
}, {
  query: t.Object({
    a: t.Integer(),
    b: t.Integer(),
  }),
  response: t.Number(),
  transform({ query }) {
    query.a = Number(query.a)
    query.b = Number(query.b)
  },
})

app.listen(3000)

执行bun dev 运行项目,浏览器输入http://localhost:3000/swagger,就能看到swagger文档了

也是成功的运行成功了。

相关代码截图

/src/index.ts

/src/worker.ts

写在最后,说一下,本人也是刚学一会,没多久,写个文章想问一下有没有交流群之类的,一起学习一下,对elysia和prisma还是挺感兴趣的,如果文章中哪里有问题欢迎及时指正。

相关推荐
80530单词突击赢几秒前
JavaWeb进阶:SpringBoot核心与Bean管理
java·spring boot·后端
爬山算法20 分钟前
Hibernate(87)如何在安全测试中使用Hibernate?
java·后端·hibernate
WeiXiao_Hyy38 分钟前
成为 Top 1% 的工程师
java·开发语言·javascript·经验分享·后端
苏渡苇44 分钟前
优雅应对异常,从“try-catch堆砌”到“设计驱动”
java·后端·设计模式·学习方法·责任链模式
吃杠碰小鸡1 小时前
高中数学-数列-导数证明
前端·数学·算法
long3161 小时前
Aho-Corasick 模式搜索算法
java·数据结构·spring boot·后端·算法·排序算法
kingwebo'sZone1 小时前
C#使用Aspose.Words把 word转成图片
前端·c#·word
xjt_09011 小时前
基于 Vue 3 构建企业级 Web Components 组件库
前端·javascript·vue.js
rannn_1111 小时前
【苍穹外卖|Day4】套餐页面开发(新增套餐、分页查询、删除套餐、修改套餐、起售停售)
java·spring boot·后端·学习
我是伪码农2 小时前
Vue 2.3
前端·javascript·vue.js