使用Fastify让Electron protocol更优雅当我们在使用 electron 开发应用时,通常使用invo
前言
当我们在使用 electron 开发应用时,通常使用ipcRenderer.invoke(channel, ...args)
来进行渲染进程和主进程的交互,但扩展性不够强,所以本篇将介绍如何使用protocol
和Fastify
相结合的方式,极大的简化渲染进程和主进程的通信。
阅读须知:
- 代码使用 TypeScript,vue-setup
- 脚手架 electron-vite
- 开发环境:window,node:v20.9.0,pnpm:v8.11.0
简单实现
pnpm create @quick-start/electron
创建好项目后,我们在src/main/index.ts
中首先注册一个协议,如下
protocol.registerSchemesAsPrivileged([
{
scheme: "app",
privileges: {
bypassCSP: true,
standard: true,
secure: true,
supportFetchAPI: true,
},
},
]);
接下来我们在实现其handle
方法,对访问的url
进行拦截,并返回一个简单的对象,如下
protocol.handle("app", (request) => {
return new Response("<h1>hello, world</h1>", {
headers: { "content-type": "text/html" },
});
});
实现效果如下
进阶
接下来我们结合Fastify
让逻辑的处理更为清晰,首先我们定义一个Fastify
实例如下
import { protocol } from "electron";
import Fastify, { FastifyInstance } from "fastify";
const fastify: FastifyInstance = Fastify({
logger: true,
});
fastify.get("/", async (request, reply) => {
return { hello: "world" };
});
但是我们并不需要创建一个 server 服务,所以并不需要
fastify.listen(3000, (err, address) => {
if (err) throw err;
console.log(`server listening on ${address}`);
});
我们接下来扩展protocol.handle
方法,首先从handle
方法的入参Request
中拿到我们需要的字段
const options: any = {
method: request.method,
url: url,
body: request.body,
};
然后调用fastify.inject()
方法从而实现处理
const response = await this.server.inject(options);
最后组装Response
对象,进行返回
const response: Response = {
statusCode: response.statusCode,
headers: response.headers,
body: response.body,
};
从而实现了对protocol
通信的优化
最终效果
完整代码
- 主进程
import { protocol } from "electron";
import Fastify, { FastifyInstance } from "fastify";
const fastify: FastifyInstance = Fastify({
logger: true,
});
fastify.get("/user", async (request, reply) => {
return {
name: "user",
age: 18,
};
});
protocol.handle("app", async (request: Request) => {
let url = request.url.replace("app://", "/");
if (url.endsWith("/")) {
url = url.slice(0, -1);
}
const options: any = {
method: request.method,
url: url,
body: request.body,
};
console.log(options);
const response = await this.server.inject(options);
return new Response(response.body, {
status: response.statusCode,
});
});
- web
fetch("app://user").then(async (res) => {
console.log(await res.json());
});
后记
欢迎大家沟通交流,如果对你有帮助,希望点赞支持一下,谢谢👏
转载自:https://juejin.cn/post/7384376473648742419