You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Servo/ipc_channel实现进程间消息传递遇阻,求双向通信示例

用servo/ipc_channel实现主进程与子进程双向消息传递的简易示例

核心实现代码

以下是完整的单文件示例,主进程通过命令行参数判断是否启动子进程逻辑:

use ipc_channel::ipc::{IpcOneShotServer, IpcReceiver, IpcSender};
use std::env;
use std::process::Command;

// 定义可序列化的消息类型,支持文本和发送器传递
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
enum Message {
    Text(String),
    Sender(IpcSender<Message>),
}

fn main() {
    // 处理子进程逻辑
    if let Some(arg) = env::args().nth(1) {
        if arg == "child" {
            let server_name = env::args().nth(2).unwrap();
            run_child(&server_name);
            return;
        }
    }

    // 主进程逻辑
    // 1. 创建一次性IPC服务器,获取服务器名称和接收器
    let (server_name, server_receiver) = IpcOneShotServer::<Message>::new().unwrap();

    // 2. 启动子进程,传递服务器名称作为参数
    let child = Command::new(env::current_exe().unwrap())
        .arg("child")
        .arg(&server_name)
        .spawn()
        .unwrap();

    // 3. 接收子进程发送的自身发送器,建立反向通信通道
    let (child_sender, _) = server_receiver.accept().unwrap();
    println!("主进程:已获取子进程发送器");

    // 4. 发送初始消息
    child_sender.send(Message::Text("来自主进程的问候".to_string())).unwrap();
    println!("主进程:已发送初始消息");

    // 5. 循环接收子进程消息
    loop {
        match child_sender.recv() {
            Ok(msg) => match msg {
                Message::Text(text) => println!("主进程收到:{}", text),
                _ => println!("主进程收到未知消息类型"),
            },
            Err(e) => {
                println!("主进程接收失败:{}", e);
                break;
            }
        }
    }

    child.wait().unwrap();
}

// 子进程执行逻辑
fn run_child(server_name: &str) {
    // 1. 连接主进程的IPC服务器,获取主进程发送器
    let main_sender = IpcSender::<Message>::connect(server_name).unwrap();
    println!("子进程:已连接主进程服务器");

    // 2. 创建子进程自身的收发器,用于向主进程发送消息
    let (child_sender, child_receiver) = ipc_channel::ipc::channel().unwrap();

    // 3. 将子进程发送器传递给主进程,建立双向通信
    main_sender.send(Message::Sender(child_sender)).unwrap();
    println!("子进程:已发送自身发送器给主进程");

    // 4. 发送初始消息
    main_sender.send(Message::Text("来自子进程的问候".to_string())).unwrap();
    println!("子进程:已发送初始消息");

    // 5. 循环接收主进程消息
    loop {
        match child_receiver.recv() {
            Ok(msg) => match msg {
                Message::Text(text) => println!("子进程收到:{}", text),
                _ => println!("子进程收到未知消息类型"),
            },
            Err(e) => {
                println!("子进程接收失败:{}", e);
                break;
            }
        }
    }
}

依赖配置

在Cargo.toml中添加必要依赖:

[dependencies]
ipc-channel = "0.15.0"
serde = { version = "1.0", features = ["derive"] }

关键问题解析

  1. 从IpcOneShotServer接收消息
    IpcOneShotServer是用于建立初始连接的一次性服务器:
  • 主进程通过IpcOneShotServer::new()生成服务器名称和接收器
  • 子进程通过IpcSender::connect(server_name)连接后,主进程调用server_receiver.accept()即可接收子进程发送的第一条消息(这里我们传递子进程的发送器,用于反向通信)
  1. 双向通信的嵌套通道逻辑
    ipc_channel的通道是单向的(发送器仅能发送,接收器仅能接收),双向通信需要两个单向通道配合:
  • 主→子通道:子进程连接服务器后获得的main_sender
  • 子→主通道:子进程创建自身通道后,将child_sender发送给主进程,主进程通过这个发送器向子进程发消息,子进程用对应的child_receiver接收

这种传递发送器的方式就是所谓的“嵌套通道”,本质是交换通信端点,实现双向交互。

内容的提问来源于stack exchange,提问作者yosemeti

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.07 12:01:08