likes
comments
collection
share

使用Fastify让Electron protocol更优雅当我们在使用 electron 开发应用时,通常使用invo

作者站长头像
站长
· 阅读数 74

前言

当我们在使用 electron 开发应用时,通常使用ipcRenderer.invoke(channel, ...args)来进行渲染进程和主进程的交互,但扩展性不够强,所以本篇将介绍如何使用protocolFastify相结合的方式,极大的简化渲染进程和主进程的通信。

阅读须知:

  1. 代码使用 TypeScript,vue-setup
  2. 脚手架 electron-vite
  3. 开发环境: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让Electron protocol更优雅当我们在使用 electron 开发应用时,通常使用invo

进阶

接下来我们结合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通信的优化

最终效果

使用Fastify让Electron protocol更优雅当我们在使用 electron 开发应用时,通常使用invo

完整代码

  • 主进程
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
评论
请登录