【问题标题】:Rust doesn't accept input from stdin from native messaging - firefoxRust 不接受来自本地消息传递的标准输入的输入 - firefox
【发布时间】:2020-06-01 05:22:09
【问题描述】:

我正在使用来自 firefox 的 Web API 制作本机消息传递应用程序。该扩展程序应该调用一个解析标准输入的应用程序,然后根据它解析的一些数据调用我的另一个 rust 应用程序,但是没有明显的原因,rust 应用程序不接受来自 firefox 的输入(当我这样做时它可以工作手动)。 这是扩展的代码:

/*
On a click on the browser action, send the app a message.
*/
browser.browserAction.onClicked.addListener(() => {
  console.log("Sending:  ping");
  var sending = browser.runtime.sendNativeMessage(
    "themefox_manager",
    "ping");
  sending.then(onResponse, onError);
});


function onResponse(response) {
  console.log("Received " + response);
}


function onError(error) {
  console.log(`Error: ${error}`);
}

这是 rust 应用程序的代码:

use std::fs;
use std::io;
use std::io::prelude::*;

fn main() {
    let stdin = io::stdin();
    for line in stdin.lock().lines() {
        let mut file = fs::File::create("/home/user/filename.txt").unwrap();
        //
        if line.unwrap() == "ping" {
            file.write_all(b"TEST").expect("Error");
        }
    }
}

奇怪的是,当我关闭 firefox 时,我的主目录中的文本文件首先出现,而不是在应用程序启动时出现。而且它也没有文本 TEST。

感谢您的帮助!

干杯

【问题讨论】:

    标签: firefox rust stdin


    【解决方案1】:

    我设法从this crate 中获得了一些解决方案。

    快速说明:“如果您想跳过所有代码并立即从模板存储库开始编码,请浏览到此解决方案的底部,您应该能够在那里找到更多信息。”

    读取输入然后返回的代码如下:

    pub fn read_input<R: Read>(mut input: R) -> io::Result<serde_json::Value> {
        let length = input.read_u32::<NativeEndian>().unwrap();
        let mut buffer = vec![0; length as usize];
        input.read_exact(&mut buffer)?;
        let json_val: serde_json::Value = serde_json::from_slice(&buffer).unwrap();
        Ok(json_val)
    }
    

    代码的作用是读取输入,该输入作为参数传递给函数,然后读取它并将其解析为 json var 并返回它的 sucess/err 值。

    该代码在 main.rs 文件中使用如下:

    let json_val = match lib::read_input(io::stdin()) {
        Err(why) => panic!("{}", why.to_string()),
        Ok(json_val) => json_val,
    };
    

    这里将输入作为参数传递给 read_input 函数。

    为了发送代码,我使用了以下函数:

    pub fn write_output<W: Write>(mut output: W, value: &serde_json::Value) -> io::Result<()> {
        let msg = serde_json::to_string(value)?;
        let len = msg.len();
        // Chrome won't accept a message larger than 1MB
        if len > 1024 * 1024 {
            panic!("Message was too large", length: {}, len)
        }
        output.write_u32::<NativeEndian>(len as u32)?;
        output.write_all(msg.as_bytes())?;
        output.flush()?;
        Ok(())
    }
    

    获取标准输出和作为参数传递的消息。然后该函数将消息写入输出(通常是标准输出,也可以是用于调试目的的文件)。

    调用函数write_output的代码如下:

    
        let response = serde_json::json!({ "msg": "pong" });
        match lib::write_output(io::stdout(), &response) {
            Err(why) => panic!("{}", why.to_string()),
            Ok(_) => (),
        };
    
    

    项目使用了这些依赖,所以一定要把它们添加到Cargo.toml

        "byteorder" = "*"
        "serde_json" = "*"
    

    main.rs 文件的导入是:

    mod lib;
    use std::io;
    

    对于两个函数所在的 lib.rs 文件:

    extern crate serde_json;
    use byteorder::{NativeEndian, ReadBytesExt, WriteBytesExt};
    use std::error::Error;
    use std::fs;
    use std::io;
    use std::io::{Read, Write};
    

    我还创建了一个 git 模板 repo,这样你就可以快速开始,你可以找到它here

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-02-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-02-07
      相关资源
      最近更新 更多