目录

Inter-Process Communication

How to send messages from the renderer process to the main process and receive a response.

The renderer process runs in a sandbox that prevents direct access to Node.js APIs and operating system resources. Inter-Process Communication (IPC) is the mechanism that bridges this gap. When you need to perform a privileged operation in the renderer process you can use IPC to send a message to the main process and receive a response.

Overview 

The framework uses Protocol Buffers (Protobuf) to define a type-safe interface between the renderer process and the main process. The generated project is configured with all the required dependencies and includes the code demonstrating how to send and handle IPC messages between the renderer process and the main process.

The workflow consists of the following steps:

  1. Define messages and services in the src/renderer/proto/ directory.
  2. Generate stubs for both the renderer process and the main process.
  3. Implement the service methods in the main process.
  4. Call the service methods from the renderer process.

Let’s go through the workflow step by step in the sections below.

Defining messages and services 

Messages and services are the core of your IPC contract:

  • Messages define the data shape passed between processes.
  • Services define the RPC methods the renderer process can call.

Here is an example of the src/renderer/proto/greet.proto file you can find in the generated project:

syntax = "proto3";

import "google/protobuf/wrappers.proto";

// Message definition.
message Person {
  string name = 1;
}

// Service definition.
service GreetService {
  rpc SayHello(Person) returns (google.protobuf.StringValue);
}

Generating code 

Once you have defined the messages and services, you can generate the code for both the renderer process and the main process using the following command:

npm run mobrowser gen

This command reads your Protobuf definitions and generates TypeScript bindings:

  • The code for the main process will be placed in the src/main/gen directory.
  • The code for the renderer process will be placed in the src/renderer/gen directory.
.vscode/
assets/
resources/
src/
├── main/
    ├── gen/
    ├── index.ts
├── renderer/
    ├── gen/
    ├── proto/
        ├── greet.proto
mobrowser.conf.json
package.json
tsconfig.json
tsconfig.node.json
vite.config.ts

Implementing services in the main process 

In the main process, implement the generated service methods. This is where you can implement the privileged logic, such as filesystem access, native APIs, process management, etc.

Here is an example of the service implementation in the src/main/index.ts file:

import { ipc } from '@mobrowser/api';
import { Person } from './gen/greet';
import { GreetService } from './gen/ipc_service';

// Handle the IPC calls from the renderer process.
ipc.registerService(GreetService({
  async SayHello(person: Person) {
    return { value: `Hello, ${person.name}!` };
  },
}))

Calling services from the renderer process 

In the renderer process, import the generated client and call service methods as regular async functions. Here is an example demonstrating how to call the generated service methods from the renderer process:

import { ipc } from "./gen/ipc";

ipc.greet.SayHello({ name: 'John' }).then((message) =>
  console.log(message.value) // Hello, John!
)